# DOM
點擊關注本[公眾號](http://www.hmoore.net/book/dsh225/javascript_vue_css/edit#_118)獲取文檔最新更新,并可以領取配套于本指南的《**前端面試手冊**》以及**最標準的簡歷模板**.
[TOC]
前端框架大行其道的今天,我們直接操作DOM的時候變得更少了,因此不妨復習一下DOM的[基本知識](http://luopq.com/2015/11/30/javascript-dom/)
## DOM的事件模型是什么?
DOM之事件模型分腳本模型、內聯模型(同類一個,后者覆蓋)、動態綁定(同類多個)
~~~
<body>
<!--行內綁定:腳本模型-->
<button onclick="javascrpt:alert('Hello')">Hello1</button>
<!--內聯模型-->
<button onclick="showHello()">Hello2</button>
<!--動態綁定-->
<button id="btn3">Hello3</button>
</body>
<script>
/*DOM0:同一個元素,同類事件只能添加一個,如果添加多個,
* 后面添加的會覆蓋之前添加的*/
function shoeHello() {
alert("Hello");
}
var btn3 = document.getElementById("btn3");
btn3.onclick = function () {
alert("Hello");
}
/*DOM2:可以給同一個元素添加多個同類事件*/
btn3.addEventListener("click",function () {
alert("hello1");
});
btn3.addEventListener("click",function () {
alert("hello2");
})
if (btn3.attachEvent){
/*IE*/
btn3.attachEvent("onclick",function () {
alert("IE Hello1");
})
}else {
/*W3C*/
btn3.addEventListener("click",function () {
alert("W3C Hello");
})
}
</script>
~~~
## DOM的事件流是什么?
事件就是文檔或瀏覽器窗口中發生的一些特定的交互瞬間,而事件流(又叫事件傳播)描述的是從頁面中接收事件的順序。
### 事件冒泡
事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,然后逐級向上傳播到較為不具體的節點。
看如下例子:
~~~
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<body>
<div></div>
</body>
</html>
~~~
如果單擊了頁面中的`<div>`元素,那么這個click事件沿DOM樹向上傳播,在每一級節點上都會發生,按照如下順序傳播:
1. div
2. body
3. html
4. document
### 事件捕獲
事件捕獲的思想是不太具體的節點應該更早接收到事件,而最具體的節點應該最后接收到事件。事件捕獲的用意在于在事件到達預定目標之前就捕獲它。
還是以上一節的html結構為例:
在事件捕獲過程中,document對象首先接收到click事件,然后事件沿DOM樹依次向下,一直傳播到事件的實際目標,即`<div>`元素
1. document
2. html
3. body
4. div
### 事件流
事件流又稱為事件傳播,DOM2級事件規定的事件流包括三個階段:事件捕獲階段(capture phase)、處于目標階段(target phase)和事件冒泡階段(bubbling phase)。

觸發順序通常為
1. 進行事件捕獲,為截獲事件提供了機會
2. 實際的目標接收到事件
3. 冒泡階段,可以在這個階段對事件做出響應
## 什么是事件委托
事件委托就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件.
在綁定大量事件的時候往往選擇事件委托。
~~~
<ul id="parent">
<li class="child">one</li>
<li class="child">two</li>
<li class="child">three</li>
...
</ul>
<script type="text/javascript">
//父元素
var dom= document.getElementById('parent');
//父元素綁定事件,代理子元素的點擊事件
dom.onclick= function(event) {
var event= event || window.event;
var curTarget= event.target || event.srcElement;
if (curTarget.tagName.toLowerCase() == 'li') {
//事件處理
}
}
</script>
~~~
優點:
* 節省內存占用,減少事件注冊
* 新增子對象時無需再次對其綁定事件,適合動態添加元素
局限性:
* focus、blur 之類的事件本身沒有事件冒泡機制,所以無法委托
* mousemove、mouseout 這樣的事件,雖然有事件冒泡,但是只能不斷通過位置去計算定位,對性能消耗高,不適合事件委托
* * *
## DOM變動事件的用法
DOM2級的変動事件是為XML或html的DOM設計的,不特定于某種語言。
一:變動事件的分類有7種,最常用的瀏覽器支持最多的有3種,下面黑體?
1. **DOMSubtreeModified**:在DOM結構中發生任何變化時觸發;
2. **DOMNodeInserted**:在一個節點作為子節點被插入到另一個節點中時觸發;
3. **DOMNodeRemoved**:在節點從其父節點中被移除時觸發;
4. DOMNodeInsertedIntoDocument:在一個節點被直接插入文檔中或者通過子樹間接插入文檔后觸發。在DOMNodeInserted之后觸發;
5. DOMNodeRemovedFromDocument:在一個節點被直接從文檔中刪除或通過子樹間接從文檔中移除之前觸發。在DOMNodeRemoved之后觸發。
6. DOMAttrModified:在特性被修改之后觸發;
7. DOMCharacterDataModified:在文本節點的值發生變化的時候觸發。
二:刪除節點檢測?
首先觸發的是DOMNodeRemoved事件,它對應的event對象中的target屬性值是被刪除的節點,relatedNode屬性值是被刪除節點的父節點,該事件會冒泡; 其次出發的是DOMNodeRemovedFromDocument事件,它對應的event對象中的target屬性值為指定的被刪除的子節點。只有綁定到它的子節點上才能被觸發。 最后觸發的是DOMSubtreeModified事件。這個事件對應event對象中的target屬性是被移除節點的父節點。
https://www.cnblogs.com/nlyangtong/p/11230187.html
## 公眾號
想要實時關注筆者最新的文章和最新的文檔更新請關注公眾號**程序員面試官**,后續的文章會優先在公眾號更新.
**簡歷模板**:關注公眾號回復「模板」獲取
《**前端面試手冊**》:配套于本指南的突擊手冊,關注公眾號回復「fed」獲取

- 前言
- 指南使用手冊
- 為什么會有這個項目
- 面試技巧
- 面試官到底想看什么樣的簡歷?
- 面試回答問題的技巧
- 如何通過HR面
- 推薦
- 書籍/課程推薦
- 前端基礎
- HTML基礎
- CSS基礎
- JavaScript基礎
- 瀏覽器與新技術
- DOM
- 前端基礎筆試
- HTTP筆試部分
- JavaScript筆試部分
- 前端原理詳解
- JavaScript的『預解釋』與『變量提升』
- Event Loop詳解
- 實現不可變數據
- JavaScript內存管理
- 實現深克隆
- 如何實現一個Event
- JavaScript的運行機制
- 計算機基礎
- HTTP協議
- TCP面試題
- 進程與線程
- 數據結構與算法
- 算法面試題
- 字符串類面試題
- 前端框架
- 關于前端框架的面試須知
- Vue面試題
- React面試題
- 框架原理詳解
- 虛擬DOM原理
- Proxy比defineproperty優劣對比?
- setState到底是異步的還是同步的?
- 前端路由的實現
- redux原理全解
- React Fiber 架構解析
- React組件復用指南
- React-hooks 抽象組件
- 框架實戰技巧
- 如何搭建一個組件庫的開發環境
- 組件設計原則
- 實現輪播圖組件
- 性能優化
- 前端性能優化-加載篇
- 前端性能優化-執行篇
- 工程化
- webpack面試題
- 前端工程化
- Vite
- 安全
- 前端安全面試題
- npm
- 工程化原理
- 如何寫一個babel
- Webpack HMR 原理解析
- webpack插件編寫
- webpack 插件化設計
- Webpack 模塊機制
- webpack loader實現
- 如何開發Babel插件
- git
- 比較
- 查看遠程倉庫地址
- git flow
- 比較分支的不同并保存壓縮文件
- Tag
- 回退
- 前端項目經驗
- 確定用戶是否在當前頁面
- 前端下載文件
- 只能在微信中訪問
- 打開新頁面-被瀏覽器攔截
- textarea高度隨內容變化 vue版
- 去掉ios原始播放大按鈕
- nginx在MAC上的安裝、啟動、重啟和關閉
- 解析latex格式的數學公式
- 正則-格式化a鏈接
- 封裝的JQ插件庫
- 打包問題總結
- NPM UI插件
- 帶你入門前端工程
- webWorker+indexedDB性能優化
- 多個相鄰元素切換效果出現邊框重疊問題的解決方法
- 監聽前端storage變化