普歌-碼上鴻鹄團隊-js進階bom、dom總結筆記
- 定義
-
- 一、DOM
-
- 1. dom樹
- 2. document對象
-
- 2.1 常用屬性
- 2.2 擷取文檔元素
- 2.3 擷取特殊元素(body,html)
- 3. 元素對象
-
- 3.1 Element
- 3.2 HTMLCollection
- 4. 節點操作
-
- 4.1 節點層級
- 5.DOM事件
-
- 5.1 滑鼠事件
- 5.2 鍵盤事件
- 5.3 注冊事件
- 5.4 觸屏事件對象(touchEvent)
- 5.5 事件流
- 5.6 事件對象
- 5.7 預設行為與冒泡阻止
- 5.8 事件委托
- 二、BOM
-
- 1. Window對象
-
- 1.1 屬性
- 1.2 方法
- 1.3 事件
- 2. location對象
-
- 2.1 屬性
- 2.2 方法
- 2.3 URL(同一資源定位符)
- 3. navigator對象
- 4. history對象
- 5. 定時器
- 6. JS執行機制
-
- 6.1 JS是單線程
- 6.2 同步和異步
- 6.3 執行機制
- 三、網頁特效
-
- 1. 元素偏移量offset
- 2. 元素可視區client
- 3. 元素滾動scroll
- 四、動畫
-
- 1.封裝動畫函數
- 2. 緩動動畫
- 五、本地存儲
-
- 1. window.sessionStroage
- 2. window.localStorage
- ~有問題可以評論區留言,喜歡的小夥伴可以點贊、關注、收藏哦 ♥ ♥ ♥ \color{red}{♥♥♥} ♥♥♥
定義
- Dom
- 文檔對象模型(Document Object Model,簡稱DOM),是W3C組織推薦的處理HTML/XML的标準API接口.
- 提供對文檔的結構化描述,定義方式對結構進行通路并進行修改結構,樣式和内容
- 頂級對象時是document
- Bom
- 浏覽器對象模型(Browser Object Model,簡稱BOM)
- 提供了獨立于内容而與浏覽器視窗互動的對象
- 頂級對象是window
- DOM和BOM的差別(對比圖)
DOM | BOM |
---|---|
文檔對象模型 | 浏覽器對象模型 |
DOM把[文檔]當做一個[對象]來看待 | BOM把[浏覽器]當做一個[對象來看待 |
DOM的頂級對象是document | BOM的頂級對象是window |
DOM主要學習的是操作頁面元素 | BOM學習的是浏覽器視窗互動的一些對象 |
DOM是W3C标準規範 | BOM是浏覽器廠商在各自浏覽器上定義的,相容性差 |
- dom和bom的關系結構圖
一、DOM
1. dom樹
- 文檔: 一個頁面就是一個文檔,DOM中使用document表示
- 元素: 頁面中的所有标簽都是元素,DOM中使用element表示
- 節點: 網頁中的所有内容都是節點(标簽,屬性,文本,注釋等),DOM中使用node表示
2. document對象
提示:
d o c u m e n t 對 象 對 應 整 個 文 檔 , 整 個 文 檔 相 關 的 操 作 和 編 程 的 a p i 都 是 通 過 d o c u m e n t 對 象 進 行 實 現 \color{#000}{ document對象對應整個文檔,整個文檔相關的操作和程式設計的api都是通過document對象進行實作} document對象對應整個文檔,整個文檔相關的操作和程式設計的api都是通過document對象進行實作
2.1 常用屬性
- URL: 擷取目前文檔的URL位址,隻讀
- title: 擷取目前文檔Head中的title的文字内容,可寫入修改
document.title
2.2 擷取文檔元素
// 根據id,傳回Element
getElementById('元素id')
//根據标簽名擷取(如果是*,傳回所有),傳回HTMLCollection集合
getElementsByTagName('标簽名')
// 根據name屬性,傳回NodeList集合
getElementsByName(name)
//根據元素類名傳回元素對象集合
getElementByClassName('元素類名')
// 根據css選擇器傳回第一個元素對象
querySelector('選擇器')
// 根據css選擇器傳回所有指定元素,多個選擇器以逗号分隔querySelectorAll( 'p,a')
querySelectorAll('選擇器')
2.3 擷取特殊元素(body,html)
// 擷取body元素
const bodyElem = document.body; //傳回body元素對象
// 擷取Html元素
const htmlElem = document.documentElement; //傳回html元素對象
3. 元素對象
3.1 Element
// Element對象是所有标簽元素的基礎對象,封裝了所有标簽元素的公共方法與屬性
// 常用屬性
Element.attributes // 獲得所有屬性key-value集合
Element.className // 獲得類名(可讀寫)=>idea:elem.className = 'pink',然後再css定義
// 注意:此方法會覆寫原有類名
============================^_^============================
Element.classList // 傳回一個元素的類屬性的實時 DOMTokenList 集合(隻讀),通過其内部方法修改
// ie10+,
============================^_^============================
Element.id // 擷取元素id
Element.innerHTML // 擷取元素内部包裹的html标簽字元串(可讀寫)
Element.innerText // 擷取元素内部文本,标簽不識别會直接進行顯示(可讀寫)
Element.tagName // (隻讀)擷取元素的标簽名字元串
Element.style // 擷取/修改style樣式,如Element.style.backgroundColor
// 常用方法
Element.getAttribute(attrName) // 傳回屬性的字元串值,适合擷取自定義屬性data-
Element.removeAttribute(attrName) // 從指定的元素中删除一個屬性
Element.setAttribute(attrName,value)// 設定屬性
Element.hasAttribute(attrName) // 檢測屬性是否存在
Element.getElementsByClassName() // 擷取後代元素根據className
Element.getElementsByTagName() // 擷取後代元素根據tagName
...
Element.dataset.index | Element.dataset['index'] // 用于擷取data-自定義屬性(h5新增),支援駝峰命名擷取(ie11+)
3.2 HTMLCollection
// HTMLCollection對象,是僞數組。元素的動态集合,提供了用來從該集合選擇元素的方法和屬性,當其所包含的文檔結構發生改變時,會自動更新.
// 常用屬性
HTMLCollection.length // 傳回集合中子元素的數組
============================^_^============================
// 常用方法
HTMLCollection.item() // 根據給定的索引(從0開始),傳回具體的節點
HTMLCollection.namedItem() // 根據 Id 傳回指定節點,或者作為備用,根據字元串所表示的 name 屬性來比對
4. 節點操作
WARNING:
一 般 的 , 節 點 至 少 擁 有 n o d e T y p e ( 節 點 類 型 ) , n o d e N a m e ( 節 點 名 稱 ) , n o d e V a l u e ( 節 點 值 ) \color{#000}{ 一般的,節點至少擁有nodeType(節點類型),nodeName(節點名稱),nodeValue(節點值)} 一般的,節點至少擁有nodeType(節點類型),nodeName(節點名稱),nodeValue(節點值)
- 元素節點 nodeType為1
- 屬性節點 nodeType為2
- 文本節點 nodeType為3(文本幾點包含文字,空格,換行等)
4.1 節點層級
- 父級節點
//parentNode屬性可傳回某節點的父節點,注意是最近的一個父節點(親爸爸)
node.parentNode // 找不到傳回null
- 子節點
parentNode.childNodes // 注意: 會傳回3種子節點=>如果指向某種節點,可通過nodeType判斷
parentNode.firstChild // 傳回第一個子節點(會包括3種節點)
parentNode.lastChild // 擷取最後一個子節點(會包括3種節點)
parentNode.children // 隻擷取子元素節點
parentNode.firstElementChild // 擷取第一個子元素節點(ie9+)
parentNode.lastElementChild // 擷取最後一個子元素節點(ie9+)
*注意:
parentNode.childNodes 傳回值裡包含了所有子節點,包括元素節點,文本節點等
- 兄弟節點
node.nextSibling // 目前元素的下一個兄弟節點(會包含3種節點)
node.previousSibling // 目前元素的上一個兄弟節點(會包含3種節點)
node.nextElementSibling // 目前元素的下一個兄弟元素節點(IE9+)
node.previousElementSibling // 目前元素的上一個兄弟元素節點(IE9+)
- 節點建立與添加
// 建立節點
let li = document.createElement('li');
// 在已有子節點後面追加節點(不會覆寫原有節點)
parentNode.appendChild(li);
// 在指定子節點前面追加節點(不會覆寫原有節點)
parentNode.insertBefore(child,指定子元素)
- 節點移除
- 節點複制
node.cloneNode() // 拷貝node節點=>淺拷貝,隻拷貝标簽,不拷貝裡面内容
node.cloneNode(true)// 拷貝node節點=>深度拷貝,拷貝标簽以及裡面内容
- 三種動态建立元素的差別
document.write('<div>123</div>') // 注意:當頁面文檔流加載完畢,會進行重繪
element.innerHTML = '<div>123</div>' // 不要重複拼接字元串,記憶體消耗過大
document.createElement()
5.DOM事件
5.1 滑鼠事件
滑鼠事件 | 觸發條件 |
---|---|
onclick | 滑鼠點選左鍵觸發 |
onmouseover | 滑鼠經過觸發 |
onmouseout | 滑鼠離開觸發 |
onfocus | 獲得滑鼠焦點觸發 |
onblur | 失去滑鼠焦點觸發 |
onmousemove | 滑鼠移動觸發 |
onmouseup | 滑鼠彈起觸發 |
onmousedown | 滑鼠按下觸發 |
oncontextmenu | 阻止滑鼠右鍵菜單(阻止預設行為) |
onselectstart | 禁止滑鼠選取内容(阻止預設行為) |
onselect | 禁止複制(阻止預設行為) |
- mouseenter和mouseover差別
mouseover經過自身會觸發,經過子級也會再次觸發(支援事件冒泡).mouseenter隻有經過自身盒子才觸發(不支援事件冒泡)
備注:mouseover搭配mouseout;mouseenter搭配mouseleave
5.2 鍵盤事件
三個事件的執行順序: keydown > keypress > keyup
鍵盤事件 | 觸發條件 |
---|---|
keyup | 某個鍵盤按鍵松開觸發 |
keydown | 某個鍵盤按鍵按下時觸發,隻要不松開會一直觸發 |
keypress | 某個鍵盤按鍵按下時觸發,不識别功能鍵(ctrl,上下箭頭等),隻要不松開會一直觸發 |
5.3 注冊事件
注:注冊事件有兩種方式:傳統方式和監聽方式
- 傳統方式: 使用on字首 => 事件注冊具有唯一性,後者會覆寫前者
<p onclick="alert(123)">
點選
</p>
//最後隻能彈出來"點選段落"的彈框,後者覆寫了前者
const elem = document.querySelector('p')
elem.onclick = function() {
alert('點選段落');
}
// 解綁事件
elem.onclick = null
- 監聽方式
// true:事件句柄在捕獲階段執行 false(預設):事件句柄在冒泡階段執行
// 注意:解除綁定與綁定的事件記憶體位址需要相同
let div = document.getElementById('div')
function listener(event) {
}
div.addEventListener('click',listener,true)
div.removeEventListener('click',listener,true)
// ie9以前使用attachEvent,處理相容性再用吧
div.attachEvent('onclick',method) // 綁定
div.detachEvent('onclick',method) // 移除
5.4 觸屏事件對象(touchEvent)
touchEvent是一類描述手指在觸摸平面(觸摸屏等)的狀态變化的事件對象,這類事件用于描述一個或多個觸點,使開發者可以檢測觸點的移動,觸點的增加和減少等
touchEvent對象 | 說明 |
---|---|
event.touches | 正在觸摸螢幕的所有手指的一個清單(可判斷雙指還是單指觸屏) |
event.targetTouches | 正在觸摸目前dom元素上的手指的一個清單 |
event.changedTouches | 手指狀态發生了改變的清單,從無到有,從有到無變化 |
5.5 事件流
事件分為捕獲階段與冒泡階段.捕獲階段就是事件資訊從頂層向下層傳遞的過程,冒泡時事件反應處理從底層向上層回報的過程。
js可以通過addEventListener來實作捕獲階段或者冒泡階段的事件響應方法注冊
5.6 事件對象
- 什麼是事件對象
事件對象滑鼠事件(MouseEvent),則記錄滑鼠相關資訊,如坐标等;鍵盤事件(KeyboardEvent),則記錄鍵盤相關資訊,如點選的哪個按鍵
elem.onclick = function(event) { // 此處的event就是事件對象
event.target // 傳回觸發事件的元素,不同于this傳回的是綁定事件的元素
event.srcElement // 同event.target,ie相容處理使用(ie6,7,8),非标準
event.relatedTarget // 傳回綁定事件的元素,類似于this
event.type // 擷取事件觸發類型,如click、mouseover,不帶on
event.pageX | event.pageY // 擷取光标相對于頁面的x坐标和y坐标 ie9+
event.clientX | event.clientY// 擷取光标相對可視區域的x坐标與y坐标(不受滾動條影響)
event.screenX | event.screenY// 擷取光标相對電腦螢幕的x坐标與y坐标
event.which // 代表擷取到的滑鼠或鍵盤的輸出的值,滑鼠分别為0,1,2
event.key // 擷取按下的按鍵值
event.keyCode // 擷取按下按鍵的ascii碼值
}
5.7 預設行為與冒泡阻止
- 常見html預設行為
~ Submit按鈕: 在form表單中的,送出form表單中的資料到伺服器
~ Button: 在手機浏覽器中, 若是在form中,則是submit
~ a标簽: 預設将目前頁面跳轉為a标簽中href的位址
- 阻止事件預設行為
<!-- 方式4 -->
<a onclick="javascript:;">點選</a>
<script>
const a = document.querySelector('a');
a.onclick = function(event) {
// 方式1
event.preventDefault()
// 方式2,低版本ie使用
event.returnValue()
// 方式3,addEventListener注冊方式無效
return false
}
</script>
- 阻止冒泡
<div class="parent">
<div class="child"></div>
</div>
<script>
const pElem = document.querySelector('.parent')
const cElem = document.querySelector('.child')
cElem.onclick = function(event) {
// 标準: 阻止冒泡
event.stopPropagation()
// 非标準: 阻止冒泡(ie678)
event.cancalBabel = true
}
</script>
相容性寫法:
5.8 事件委托
事件委托又叫事件代理,jquery裡面稱為事件委派
- 原理: 不再每個子節點單獨設定事件監聽器(提高了性能),而是将事件監聽器設定再父級元素上,然後利用冒泡原理影響每個子節點
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
const ul = document.querySelector('ul');
ul.addEventListener('click', event => {
// 不用單獨每個li綁定事件
//event.target可以得到我們點選的對象
console.log(event.target);
});
</script>
二、BOM
BOM沒有标準組織,ECMA有ECMA組織,DOM有W3C組織制定,而BOM還是在延用網景的标準,相容較差
- 它是js通路浏覽器視窗的一個接口
- 它是一個全局對象,定義在全局作用域的變量,函數都會變成window對象的屬性和方法 => this指向問題産生
1. Window對象
1.1 屬性
window.innerWidth // 擷取目前螢幕寬度,tip 可用來做響應式布局,還是推薦媒體查詢,flex做響應式布局
window.innerHeight // 擷取目前螢幕高度
1.2 方法
1.3 事件
- 視窗加載事件
window.onload = function() {}
// 或
window.addEventListener('load',function() {})
// window.onload是視窗加載事件,當文檔内容完全加載會觸發該事件(包括圖像,腳本檔案,css檔案等)
// window.onload傳統注冊事件隻能寫一次,如果多次會以最後一個為準,addEventListener沒有此問題
window.addEventListener('DOMContentLoaded',function(){}) // 隻要dom文檔加載完就會觸發監聽事件
- 視窗大小調整事件
// 視窗大小發生變化,就會觸發
window.onresize = function() {}
window.addEventListener('resize',function() {})
2. location對象
2.1 屬性
location對象屬性 | 傳回值 |
---|---|
location.href | 擷取或設定整個URL |
location.host | 傳回主機域名 |
location.port | 傳回端口号 |
location.pathname | 傳回路徑 |
location.search | 傳回參數 |
location.hash | 傳回錨點 |
2.2 方法
location.assign() // 跟href相同,實作跳轉頁面
location.replace() // 替換目前頁面,因為不記錄曆史,是以不能後退頁面
location.reload() // 重新加載頁面,參數為true會強制重新整理
2.3 URL(同一資源定位符)
url的一般文法格式為:
protocol://host[:port]/path/[?jquery]#fragment
https://www.baidu.com/index.html?name=andy&age=18#link
組成 | 說明 |
---|---|
protocol | 通信協定,如http,https,ftp,maito |
host | 主機(域名) |
port | 端口(預設80) |
path | 資源路徑;由零或多個"/"隔開的字元串 |
query | 參數,以鍵值對形式,通過&符來隔開 |
fragment | 錨點;#後面内容 |
3. navigator對象
navigator對象包含了很多裝置相關屬性例如作業系統,版本号等資訊
// case: 使用userAgent識别手機pc
if(navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
window.location.href = ''; //手機
} else {
window.location.href = ''; //電腦
}
4. history對象
window對象為我們提供了一個history對象,與浏覽器曆史記錄進行互動,該對象包含使用者(在浏覽器視窗中)通路過的URL
history對象方法 | 作用 |
---|---|
back() | 實作後退 |
forward() | 實作前進 |
go(參數) | 前進後退功能,參數是1: 前進一個頁面,-1:後退一個頁面 |
5. 定時器
- setInterval(重複執行,每次調用有時間延遲)
let inervalId = setInterval(code, milliseconds);
let inervalId = setInterval(function, milliseconds, param1, param2, ...)
- setTimeOut(隻執行一次,延遲delay毫秒後執行)
- 清除延遲
clearInterVal(inervalId) // 對應setInterval
clearTimeOut(inervalId) // 對應setTimeOut
- 标題跑馬燈效果實作
// 數組方式實作跑馬燈效果
setInterval(() => {
let title = [...document.title];
title.unshift(title.pop());
document.title = title.join('');
}, 500);
// 字元串方式實作跑馬燈
setInterval(() => {
let oldTitle = document.title;
let newTitle = oldTitle.slice(-1).concat(oldTitle.slice(0, -1));
document.title = newTitle;
}, 500);
6. JS執行機制
6.1 JS是單線程
javascript就是為了處理頁面中使用者的互動以及操作DOM而産生,js是單線程 => 這就意味着所有任務都需要排隊,前一個任務執行結束才能執行下一個任務。導緻某個js流程執行時間過長,頁面渲染就不連貫,造成頁面阻塞
6.2 同步和異步
為了解決js的單線程阻塞問題,利用多核CPU的計算能力,HTML5提出Web Worker标準,允許Javascript腳本建立多個線程。
- 同步: 前一個任務執行完畢才進行下一任務
注意: 同步任務都在主線程上執行,形成一個執行棧
- 異步: 前一任務執行過程種,同時執行另一任務
JS的異步任務都是通過回調函數來處理,如監聽事件,點選事件等
6.3 執行機制
- 先執行執行棧的同步任務
- 異步任務(回調函數)放到任務隊列中
- 一旦執行棧中的同步任務執行完畢,系統就會依次執行任務隊列中的異步任務
三、網頁特效
1. 元素偏移量offset
使用offset相關屬性,可以動态擷取該元素的位置(偏移),大小等.
- 注意: 傳回值是不帶機關的
- 獲得元素距離帶有定位父元素的位置
- 擷取元素自身大小(寬度和高度)
offset系列屬性 | 作用 |
---|---|
element.offsetParent | 傳回該元素帶有定位的父級元素,如何父級都沒有定位傳回body |
element.offsetTop | 傳回元素相對帶有定位父元素上方的偏移 |
element.offsetLeft | 傳回元素相對帶有定位父元素左邊框的偏移 |
element.offsetWidth | 傳回自身包括内邊距,邊框,内容區的寬度 => border+padding+width |
element.offsetHeight | 傳回自身包括内邊距,邊框,内容區的高度=> border+padding+width |
- offset與style差別(寬度)
offset | style |
---|---|
offset可以得到任意樣式表中的樣式值 | 隻能得到行内樣式表的樣式值,css中的擷取不到 |
獲得的數值沒有機關 | 獲得的是有機關的字元串 |
offsetWidth包含padding+border+width | style.width不包含padding和border |
offsetWidth隻讀 | style.width可讀寫 |
适合擷取元素大小位置 | 适合修改元素值 |
2. 元素可視區client
通過client的相關屬性可以動态擷取該元素的邊框大小,元素大小等
- 注意: 傳回值是不帶機關的
client | 作用 |
---|---|
element.clientTop | 傳回元素上邊框的大小 |
element.clientLeft | 傳回元素左邊框的大小 |
element.clientWidth | 傳回自身包括padding,内容區寬度,不包含邊框 |
element.clientHeight | 傳回自身包括padding,内容區高度,不包含邊框 |
3. 元素滾動scroll
通過scroll可以動态擷取該元素的大小,滾動距離等
- 注意: 傳回值是不帶機關的
scroll | 作用 |
---|---|
element.scrollTop | 傳回被卷去的上側距離 |
element.scrollLeft | 傳回被卷去的左側距離 |
element.scrollWidth | 傳回自身實際的寬度,不含邊框,包含padding |
element.scrollHeight | 傳回自身實際的高度,不含邊框,包含padding |
注意: 頁面的滾動距離通過window.pageXOffset擷取
四、動畫
1.封裝動畫函數
(function () {
function animate(obj, target, comeback) {
//讓我們隻有一個定時器執行
//先清除以前的定時器,隻保留目前的一個定時器執行
clearInterval(obj.timer);
obj.timer = setInterval(function () {
//步長值寫到定時器裡
//var step=Math.ceil((target-obj.offsetLeft)/10);
varstep = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
//停止動畫本質是停止定時器
clearInterval(obj.timer);
//回調函數寫到定時器結束裡面
//if(comeback){
//comeback();
//}
comeback && comeback();
}
//這個步長值改為一個慢慢變小的值步長公式:(目标值-現在的位置)/10
obj.style.left = obj.offsetLeft + step + "px";
}, 15);
}
});
2. 緩動動畫
五、本地存儲
本地存儲特性:
- 資料存儲在使用者浏覽器中
- 設定,讀取友善,甚至頁面重新整理不丢失資料
- 容量較大,sessionStorage約5M,localStorage約20M
- 隻能存儲字元串,對象轉json後再存儲
1. window.sessionStroage
- 生命周期為關閉浏覽器視窗
- 在同一視窗(頁面)下資料可以共享
- 以鍵值對的形式存儲使用
const user = { name: '隔壁老高', age: 18 }
// sessionStorage
// 存儲資料
sessionStorage.setItem('user', JSON.stringify(user, null, 2))
// 修改資料 => 重新存儲即可
// 讀取資料
sessionStorage.getItem('user')
// 删除資料
sessionStorage.removeItem('user')
// 清空資料
sessionStorage.clear()
2. window.localStorage
- 生命周期永久生效,除非手動删除否則關閉頁面也會存在
- 可以多視窗(頁面)共享(同一浏覽器可以共享資料)
- 以鍵值對的形式存儲使用
const user = { name: '隔壁老高', age: 18 }
// localStorage
// 存儲資料
localStorage.setItem('user', JSON.stringify(user, null, 2))
// 修改資料 => 重新存儲即可
// 讀取資料
localStorage.getItem('user')
// 删除資料
localStorage.removeItem('user')
// 清空資料
localStorage.clear()
~有問題可以評論區留言,喜歡的小夥伴可以點贊、關注、收藏哦 ♥ ♥ ♥ \color{red}{♥♥♥} ♥♥♥
相關推薦:wantLG的《普歌-碼上鴻鹄團隊複習總結:js 進階 ECMAScript 6(es6新特性)(上)》
- 作者:wantLG
- 本文源自:wantLG的《普歌-碼上鴻鹄JavaScript進階(BOM、DOM)總結》
- 本文版權歸作者和CSDN共有,歡迎轉載,且在文章頁面明顯位置給出原文連結,未經作者同意必須保留此段聲明,否則保留追究法律責任的權利。