冒泡和捕获
事件冒泡和事件捕获的概念是由微软和网景公司提出的,这两个概念都是为了解决页面中的事件流问题,即事件的发生顺序,首先我们先看一段代码
<div class="grandpa">
<div class ="parent">
<div class ="son">click me</div>
</div>
</div>
如果在点击上面的那个click me的,我们如何判断到底是grandpa,parent还是son的处理函数被先触发呢,为了解决这个问题,我们先来看一下事件冒泡和事件捕获的概念
事件冒泡
事件冒泡指的就是像水里的小泡泡一点点变大然后冒出水面,所以事件会从最内层先触发,然后往外层查找,直到document对象,所以上面的代码的click触发事件的顺序为:son->parent->grandpa->body->html->document
事件捕获
事件捕获是与事件冒泡的监听查找函数顺序相反,所以事件会从最外层开始触发监听函数直到最具体的元素,所以上面代码的click监听事件的顺序为:document->html->body->grandpa->parent->son
w3c的处理方式
w3c为了中和两个事件处理机制,,规定了事件流同时支持事件冒泡和事件捕获,但是可以通过使用addEventListener方法的第三个参数来控制监听函数是在哪个阶段执行
addEventListener(event,function,useCapture)
注意:event(事件名):字符串,不要使用'on'前缀,例如使用'click',不要使用'onclick' useCapture:当它的值为'true'的时候,表示监听函数在捕获阶段执行,当他为false或不传的时候,表示监听函数在冒泡阶段执行
捕获和冒泡额执行顺序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="parent">
<div class="son">click me</div>
</div>
</body>
</html>
const parent = document.querySelector('.parent')
const son = document.querySelector('.son')
parent.addEventListener('click',(e)=>{
console.log('parent div 捕获')
},true)
parent.addEventListener('click',(e)=>{
console.log('parent div 冒泡')
},false)
son.addEventListener('click',(e)=>{
console.log('son div 捕获')
},true)
son.addEventListener('click',(e)=>{
console.log('son div 冒泡')
},false)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="test">click me</div>
</body>
</html>
const test = document.querySelector('.test')
test.addEventListener('click',(e)=>{
console.log('test 冒泡')
},false)
test.addEventListener('click',(e)=>{
console.log('test 捕获')
},true)
取消冒泡
捕获是不可以取消的,但是冒泡可以,阻止冒泡的方法为给子级加event.stopPropagation(),这里的阻止冒泡不是阻止事件发生,而是阻止向外传递
<div class="parent">
<div class="son">click me</div>
const parent = document.querySelector('.parent')
const son = document.querySelector('.son')
parent.addEventListener('click',(e)=>{
console.log('parent div 捕获')
},true)
parent.addEventListener('click',(e)=>{
console.log('parent div 冒泡')
},false)
son.addEventListener('click',(e)=>{
console.log('son div 捕获')
},true)
son.addEventListener('click',(e)=>{
console.log('son div 冒泡')
event.stopPropagation()
},false)
scroll event,具体请查阅MDN文档,Bubbles,表示该事件是否冒泡,Cancelable表示是否可以取消冒泡