代码
<div class="grandparent">
<div class="parent">
<div class="son">
文字
</div>
</div>
</div>
<script>
document.querySelector(".grandparent").addEventListener("click", () => {
console.log("grandparent")
})
document.querySelector(".parent").addEventListener("click", () => {
console.log("parent")
})
document.querySelector(".son").addEventListener("click", () => {
console.log("son")
})
</script>
执行
点击"文字"后,会以上点击事件都会执行。
调用顺序
- 从外向内找监听函数,叫事件捕获
- 从内向外找监听函数,叫事件冒泡
addEventListener
事件绑定api
- IE5* : dom.attachEvent("onclick", fn)// 冒泡
- 网景: dom.addEventListener("click", fn)// 捕获
- W3C: dom.addEventListener("click", fn, bool)
如果bool不传值或者为falsy
- 就让fn走冒泡,即当前浏览器在冒泡阶段发现有dom有fn监听函数,就会调用fn,提供事件信息
如果bool为true
- 就让fn走捕获,即当前浏览器在冒泡阶段发现有dom有fn监听函数,就会调用fn,提供事件信息
注意事件结束后,e对象就不存在了
<body>
<div id="div1">
<div id="div2"></div>
</div>
</body>
div1.addEventListener('click',
(e) => {
debugger;
console.log(e, e.currentTarget)
setTimeout(
()=>{
debugger;
console.log('1',e, e.currentTarget)
},
1000
)
}
target currentTarget
区别
- e.target 用户操作的元素
- e.currentTarget 监听的元素
- this就是e.currentTarget
不推荐使用
同一个元素既有冒泡事件又有捕获事件
先监听先执行
取消冒泡
捕获不可取消,但冒泡可以
- e.stopPropagation() 可中断冒泡,浏览器不再往上走
不可取消冒泡
- scroll event 无法取消
阻止滚动冒泡
- 阻止scroll默认动作没用,因为先有滚动才有滚动事件
- 要阻止滚动,可阻止wheel和touchstart的默认动作
- 注意需要找到滚动条所在元素
- 但是滚动条还能用,可用css让滚动条width:0;
css处理
- 使用overflow:hidden 可用直接取消滚动条
- 但此时js依然可以修改scrollTop
自定义事件
浏览器自带事件
- 一共100多种事件
自定义事件
<body>
<div id="div1">点我</div>
</body>
div1.addEventListener('click',
()=>{
console.log(123)
const event = new CustomEvent(
'myEvent',
{
detail: {name: 'wt'}
}
);
div1.dispatchEvent(event)
}
)
div1.addEventListener(
'myEvent',
(e) =>{
console.log(e)
}
)
事件委托
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
document.querySelector('ul').addEventListener(
'click',
(e)=>{
console.log(e.target.innerText)
}
)
设置祖先元素,通过祖先元素触发事件,监听获取触发事件的目标是谁,从而实现一个事件处理多个元素事件的效果。
优点
- 省监听数
- 可以监听动态元素