一、什么叫事件流?
事件流:事件在目标元素和祖先元素间的触发顺序,有3个阶段:
捕获阶段:事件从最顶层元素 window 一直传递到目标元素的父元素。
目标阶段:事件到达目标元素,如果事件指定不冒泡,那就会在这里终止。
冒泡阶段:事件从目标元素父元素向上逐级传递直到最顶层元素 window。
二、JS绑定事件
1、行内绑定
<div onclick="btnClick()">click</div>
2、动态绑定
var btn=document.getElementById("btn");
btn.onclick=function(){//onclick是在冒泡阶段执行
console.log("hello");
}
3、事件侦听 addEventListener / removeEventListener
var func = () => {}
window.addEventListener(‘click’, func, false)
false是默认值,指的冒泡执行;设为true则为捕获执行。
event.stopPropagation()可以阻止事件继续传递。如果是捕获阶段执行,会阻止整个冒泡阶段的执行。
以上动态绑定和事件侦听的区别还有:动态绑定一个事件多次,后面的会覆盖前面的。而事件侦听则不会覆盖。
实例:
<html>
<head>
<style>
div {
padding: 50px;
color: #fff;
}
#div1 {
background-color: #f00;
}
#div2 {
background-color: #0f0;
}
#div3 {
background-color: #00f;
}
</style>
<script>
window.onload = () => {
const div1 = document.getElementById('div1')
const div2 = document.getElementById('div2')
const div3 = document.getElementById('div3')
// 动态绑定
div1.onclick = () => {
console.log('点击了div1')
}
div1.onclick = () => {//覆盖前述定义的事件
console.log('点击了div1---2')
}
div2.onclick = () => {
console.log('点击了div2')
}
div3.onclick = () => {
console.log('点击了div3')
}
// 事件侦听冒泡
div1.addEventListener('click', function() {
console.log('点击了div1---冒泡')
})
div1.addEventListener('click', function() {//不会覆盖前述定义的事件
console.log('点击了div1---2---冒泡')
})
div2.addEventListener('click', function() {
// event.stopPropagation()
console.log('点击了div2---冒泡')
})
div3.addEventListener('click', function() {
console.log('点击了div3---冒泡')
})
// 事件侦听捕获
div1.addEventListener('click', function() {
console.log('点击了div1---捕获')
}, true)
div2.addEventListener('click', function() {
console.log('点击了div2---捕获')
}, true)
div3.addEventListener('click', function() {
console.log('点击了div3---捕获')
}, true)
}
</script>
</head>
<body style="height: 600px; width: 600px;">
<div id="div1">
我是div1
<div id="div2">
我是div2
<div id="div3">
我是div3
</div>
</div>
</div>
</body>
</html>
总结:事件流中最重要的就是记住JS事件中默认是冒泡执行,即从子元素往父类冒泡,同时可以修改侦听代码实现捕获执行。