首先,事件的传播跟我们有没有注册过事件没有关系。
<html>
<body>
<div>
<button>click<button>
</div>
</body>
</html>
// html之上是document,在往上window
一个事件的开始传播分三个阶段:事件捕获->找到目标元素->事件冒泡
如:点击button后从开始捕获window->html->body->div->button,找到目标元素‘button’,然后开始冒泡button->div->body->html->window。如果点击的是div,则button不参与传播和冒泡
事件捕获-点击button元素
示例代码中使用addEventListener给元素注册点击事件,addEventListener的第三个参数为true表示为捕获阶段,即捕获阶段触发回调点击事件。
执行顺序:body元素->div元素->button元素(与注册顺序无关)
<body>
<div>
<button></button>
</div>
</body>
const body = document.querySelector('body')
const div = document.querySelector('div')
const button = document.querySelector('button')
body.addEventListener('click', function(){
console.log('body被点击了')
}, true)
div.addEventListener('click', function(){
console.log('div被点击了')
}, true)
button.addEventListener('click', function(){
console.log('button被点击了')
}, true)
// 控制台输出:
// body被点击了
// div被点击了
// button被点击了
事件冒泡-点击button元素
示例代码中使用addEventListener给元素注册点击事件,没有给addEventListener函数传递第三个参数,默认第三个参数为false,表示为冒泡,即冒泡阶段触发回调点击事件。
执行顺序:button元素->div元素->body元素(与注册顺序无关)
<body>
<div>
<button></button>
</div>
</body>
const body = document.querySelector('body')
const div = document.querySelector('div')
const button = document.querySelector('button')
body.addEventListener('click', function(){
console.log('body被点击了')
})
div.addEventListener('click', function(){
console.log('div被点击了')
})
button.addEventListener('click', function(){
console.log('button被点击了')
})
// 控制台输出:
// button被点击了
// div被点击了
// body被点击了
阻止事件冒泡-点击button元素
比如有个需求,点击div打印‘1’,点击button打印‘2’,如果不阻止事件冒泡的话,点击button就会先打印2,在打印1.
<body>
<div>
<button></button>
</div>
</body>
const div = document.querySelector('div')
const button = document.querySelector('button')
div.addEventListener('click', function(){
console.log('1')
})
button.addEventListener('click', function(e){
e.stopPropagation()
console.log('2')
})
// 控制台输出:
// button被点击了
获取事件源(目标阶段的dom)-事件委托
下面代码div中有100个button,要求点击button输出button的text,点击div时不触发。
可以给div注册点击事件,不需要给100button都注册点击事件
<div>
<button>1</button>
<button>2</button>
<button>3</button>
...
<button>100</button>
</div>
<script>
const div = document.querySelector('div')
div.addEventListener('click', function(e){
// e.target 获取事件源,即目标元素
if (e.target.tagName === 'BUTTON') {
console.dir(e.target.innerText)
}
})
</script>