1. 事件冒泡
事件开始时由最具体的元素(文档嵌套层次最深的那个节点)接受,然后逐级向上传播
image当点击div时事件传递由div → body → html 的顺序传播
IE9,chrome,Firefox,Opera,Safari都支持事件冒泡,并将事件冒泡到window对象。
2. 事件捕获
事件由最上级的节点接受事件,逐级向下传播直到目标元素
image当点击div时 由 body → id='button'的div → id='haha' 的div
IE9,chrome,Firefox,Opera,Safari都支持事件捕获,但是IE8和IE8以下的版本只支持事件冒泡。尽管DOM2规范要求事件应该从document对象开始传播,但是现在的浏览器实现都是从window对象开始捕获事件。
3. DOM时间流
image"DOM2级事件”规定的事件流包含三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,然后是实际的目标接收到事件,最后阶段是冒泡阶段。
4. 事件的传播是可以阻止的
在w3c中使用 event.stopPropagation()
ie下设置 window.event.cancelBubble = true
在捕获过程中stopPropagation()之后,后面的冒泡过程也不会发生
阻止事件的默认行为,在w3c中可以使用preventDefault()在IE下 window.returnValue = false
event.target 和 event.currentTarget 的区别
event.target
This property of event objects is the object the event was dispatched on. It is different than event.currentTarget when the event handler is called in bubbling or capturing phase of the event.
event.currentTarget
Identifies the current target for the event, as the event traverses the DOM. It always refers to the element the event handler has been attached to as opposed to event.target which identifies the element on which the event occurred.
读定义总是很绕,要彻底了解这两者的区别,我们要先了解浏览器中事件传递的机制冒泡和捕获。
冒泡和捕获
在页面中点击一个元素,事件是从这个元素的祖先元素中逐层传递下来的,这个阶段为事件的捕获阶段。当事件传递到这个元素之后,又会把事件逐成传递回去,直到根元素为止,这个阶段是事件的冒泡阶段。
capturing bubbling我们为一个元素绑定一个点击事件的时候,可以指定是要在捕获阶段绑定或者换在冒泡阶段绑定。 当addEventListener
的第三个参数为true
的时候,代表是在捕获阶段绑定,当第三个参数为false
或者为空的时候,代表在冒泡阶段绑定。
知道事件有这么一个穿透的过程之后,结合下面的例子,就可以很好来理解event.target
和event.currentTarget
:
<div id="a">
<div id="b">
<div id="c">
<div id="d"></div>
</div>
</div>
</div>
<script>
document.getElementById('a').addEventListener('click', function(e) {
console.log('target:' + e.target.id + '¤tTarget:' + e.currentTarget.id);
});
document.getElementById('b').addEventListener('click', function(e) {
console.log('target:' + e.target.id + '¤tTarget:' + e.currentTarget.id);
});
document.getElementById('c').addEventListener('click', function(e) {
console.log('target:' + e.target.id + '¤tTarget:' + e.currentTarget.id);
});
document.getElementById('d').addEventListener('click', function(e) {
console.log('target:' + e.target.id + '¤tTarget:' + e.currentTarget.id);
});
</script>
上面事件的绑定都是在冒泡阶段的,当我们点击最里层的元素d的时候,会依次输出:
target:d¤tTarget:d
target:d¤tTarget:c
target:d¤tTarget:b
target:d¤tTarget:a
从输出中我们可以看到,event.target
指向引起触发事件的元素,而event.currentTarget
则是事件绑定的元素,只有被点击的那个目标元素的event.target
才会等于event.currentTarget
。
如果我们把事件都绑定在捕获阶段,然后还是点击最里层的元素d,这时event.target
还依旧会指向d,因为那是引起事件触发的元素,因为event.currentTaget
指向事件绑定的元素,所以在捕获阶段,最先来到的元素是a,然后是b,接着是c,最后是d。所以输出的内容如下:
target:d¤tTarget:a
target:d¤tTarget:b
target:d¤tTarget:c
target:d¤tTarget:d
链接:
https://www.jianshu.com/p/f5245ffbd4fa
https://www.cnblogs.com/yzhihao/p/9398917.html
网友评论