# DOM
点击关注本[公众号](https://www.kancloud.cn/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)。
![2019-06-23-03-06-09](https://xiaomuzhu-image.oss-cn-beijing.aliyuncs.com/276c91e03be37bc857446b7126428ea6.png)
触发顺序通常为
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」获取
![2019-08-12-03-18-41](https://xiaomuzhu-image.oss-cn-beijing.aliyuncs.com/d846f65d5025c4b6c4619662a0669503.png)
- 前言
- 指南使用手册
- 为什么会有这个项目
- 面试技巧
- 面试官到底想看什么样的简历?
- 面试回答问题的技巧
- 如何通过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变化