# 腾讯面经整理
原文地址: https://juejin.im/post/5c19c1b6e51d451d1e06c163 (opens new window)
# 什么是事件委托
# 事件传播的三个阶段
首先明白一个事件发生后,会在子元素和父元素之间传播,这个传播分成三个阶段:
- 从window对象传导到目标节点(上层传到底层),称为“捕获阶段”
- 在目标节点上触发,称为“目标阶段”
- 从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”
# 事件冒泡和事件捕获
事件冒泡和事件捕获
- 事件冒泡:从当前触发的事件节点一级一级往上传递,依次触发,直到document为止
- 事件捕获:从document开始触发,一级一级往下传递,依次触发,直到真正事件目标为止
addEventListener() 和 removeEventListener()是用来分配和删除事件的函数。
这两个方法都需要三个参数:
- 事件名称
- 处理函数
- 【可选】指定处理函数的时期,默认值false,设为true为捕获阶段,false为冒泡阶段
# 阻止事件冒泡/捕获
- 在IE浏览器中,cancleBubble()方法
- 除IE以外其他的浏览器,stopPropagation()方法, 只会阻止冒泡或者是捕获
- stopImmediatePropagation()方法, 除了阻止冒泡捕获事件,还会阻止该元素的其他事件
# 事件委托
事件委托也叫事件代理,其原理是基于事件冒泡的
利用冒泡的原理,把本应该添加到某个元素上的事件委托给他的父级,从而减少DOM交互达到网页优化
# 事件委托的实际应用
# 多个元素共用一个监听器
当一个ul包含多个li元素, 点击多个li元素,执行同一个命令
我们可以为每一个li绑定事件,但是这样处理过于繁琐
这时我们会想到可以直接监听ul,为ul绑定事件函数,那么只要li存在于ul的内部,点击任意的一个li都会执行这条命令
- html结构
<ul>
<li>节点一</li>
<li>节点二</li>
<li>节点三</li>
<li>节点四</li>
</ul>
1
2
3
4
5
6
2
3
4
5
6
- css样式
ul, li{
list-style: none;
border: 1px solid PaleVioletRed;
padding: 10px;
background: LightPink;
}
li{
text-align: center;
margin: 10px;
background: #fff;
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- js
判断当前点击的元素是否为li,如果不是,执行以下的while循环,如果点击的元素为ul,直接跳出循环
var ul = document.querySelector('ul')
ul.addEventListener('click', function(e) {
var el = e.target
while(el.tagName !== 'LI') {
if (el === ul) {
el = null
break;
}
//否则,将当前元素父元素赋给el
el=el.parentNode
}
if (el) {
console.log('ok')
} else {
console.log('你点击的不是li')
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在线DENO: https://codepen.io/my729/pen/MLxPWL (opens new window)
# 用事件委托实现动态监控
当点击左下角的加号按钮时,会增加一个新的li,同时在点击li时,在控制台输出被点击的li的内容
- html结构
<ul>
<li>节点一</li>
<li>节点二</li>
<li>节点三</li>
<li>节点四</li>
</ul>
<button id=addButton>+</button>
1
2
3
4
5
6
7
2
3
4
5
6
7
- css样式
ul, li{
list-style: none;
border: 1px solid PaleVioletRed;
padding: 10px;
background: LightPink;
}
li{
text-align: center;
margin: 10px;
background: #fff;
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- js
addButton.onclick = function(){
var li = document.createElement('li')
li.textContent = 'new'
document.querySelector('ul').appendChild(li)
}
document.querySelector('ul').onclick = function(e){
console.log(e.target)
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
在线DEMO: https://codepen.io/my729/pen/YBgJGV (opens new window)
# 对promise的了解
TODO
作为一个小方向,系统学习
# onload和DOMContentLoaded执行顺序
# DOMContentLoaded事件
定义
当初始HTML文档完全被加载和解析(即所有的DOM完全解析)时触发的,无需要等待样式列表,图片,子框架完成加载
# onload事件
定义
等页面所有元素,包括图片 以及脚本等全部加载完成才触发
# 支持该事件的 HTML 标签
<body>, <frame>, <frameset>, <iframe>, <img>, <link>, <script>
1
# 支持该事件的 JavaScript 对象
image, layer, window
1