DOM事件流
事件流又称为事件传播,描述的是从页面中接收事件的顺序。如下图所示,DOM 是个树形结构,我们在页面上点击一个元素,事件对象将通过 DOM 事件流确定的 DOM 树进行传播。
事件冒泡(Bubbling Phase)
事件冒泡是IE 的事件流,事件是由最具体的元素接收,然后逐级向上传播。这种由内向外的查找事件对象方式,叫事件冒泡 。
事件捕获(Capture Phase)
事件捕获是Netscape浏览器开发团队提出的与IE截然相反的做法。从不具体的节点到最具体的节点,从最顶层的元素开始查找,逐层往下找,这种由外向内的查找事件对象方式,叫事件捕获。
事件流
事件流有三个阶段: 事件捕获阶段,目标阶段,事件冒泡阶段。
目标阶段指的是活动对象到达事件对象的事件目标。如果事件类型指示事件不会冒泡,则该事件对象将在此阶段完成后停止。
开发者可以自由选择将事件对象放在捕获阶段还是冒泡阶段
事件绑定
事件绑定 API
- ie5: xxx.attachEvent('onclick',fn) //冒泡
- 网景: xxx.addEventListener('click',fn) //捕获
- W3c: xxx.addEventListener('click',fn,bool) //bool 不传或为 falsy 走冒泡 true 走捕获
target 和 currentTarget
区别
- e.target 用户操作的元素
- e.currentTarget 程序员监听的元素
- this 是 e.currentTarget,个人不推荐使用 举例
- div>span{文字},用户点击文字
- e.target 就是 span
- e.currentTarget 就是 div
取消冒泡
捕获不可取消,但冒泡可以
- e.stopPropagation() 中断冒泡
- 一般用于封装某些独立的组件
阻止默认动作
- e.preventDefault()
有些事件不可取消冒泡 如scroll event
以 scroll event 为例,看到 Bubbles 和 Cancelable。
- Bubbles 为该事件是否冒泡,所有冒泡都可取消
- Cancelable 为开发者是否可以阻止默认事件
- 阻止 scroll 默认动作没用,因为有滚动才有滚动事件
- 要阻止滚动,可阻止 wheel 和 touchstart 的默认动作
- 但滚动条还能用,可以用 css 让滚动条 width:0
- :: -webkit -scrollbar{width:0 !important}
自定义事件
element.addEventListener('click', () => {
const event = new CustomEvent('custom', {
"detail": {name: "ggbondfucker", age: 18}
})
element.dispatchEvent(event)
})
element.addEventListener('custom', (e) => {
console.log('custom')
console.log(e)
})
事件委托
原理: 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
举个场景:比如给ul列表注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击了li,事件就会冒泡到ul身上,又因为ul有注册事件,就会触发事件监听器。 作用: 这样我们只操作了一次DOM, 省内存、可以监听动态元素 如何监听一个不存在的元素? 可以利用事件委托,监听的父元素即可。
$('ul').on('click','li',function(){
alert('hello world')
})