DOM事件机制
概念说明
- DOM事件流(event flow )存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
- 事件捕获:从外到内(从父到子)传播
- 事件冒泡:从内到外
API说明
addEventListener(event, listener, useCapture)
event----事件名称,如click,不带on
listener----事件监听函数
useCapture----是否采用事件捕获进行事件捕捉,默认为false,即采用事件冒泡方式
addEventListener在 IE11、Chrome 、Firefox、Safari等浏览器都得到支持。
代码示例
以此为父子孙三个元素绑定点击事件:
<div id="parent">
父元素
<div id="child">
子元素
</div>
</div>
<script type="text/javascript">
var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.body.addEventListener("click",function(e){
console.log("click-body");
},false);
parent.addEventListener("click",function(e){
console.log("click-parent");
},false);
child.addEventListener("click",function(e){
console.log("click-child");
},false);
</script>
- 点击子元素,会依次触发child、parent、document的点击事件,这就是事件冒泡
- 禁止冒泡:
child.addEventListener("click",function(e){
console.log("click-child");
e.stopPropagation();
},false);
- 为上面的例子再新增事件
//新增事件捕获事件代码
parent.addEventListener("click",function(e){
console.log("click-parent--事件捕获");
},true);
点击child元素,依次触发"click-parent–事件捕获"、child、parent、document
补充
为一个元素绑定多个事件,会按照绑定的顺序一次触发
btn2.addEventListener('click', event => {
console.log('btn click 1');
});
btn2.addEventListener('click', event => {
console.log('btn click 2');
});
//点击输出:
//btn click 1
//btn click 2
事件委托
将元素委托到其父元素上
一来减少内存消耗,提高性能;
二来可以一次性为动态元素绑定事件.
event.target
指向引起触发事件的元素(触发者),而event.currentTarget
则是事件绑定的元素(监听者)
说明
event.target兼容性问题
IE不支持relatedTarget属性,火狐不支持toElement属性
所以一般判断对应的属性存不存在
Event对象
event.preventDefault()
如果调用这个方法,默认事件行为将不再触发。event.stopPropagation()
方法阻止事件冒泡到父元素,阻止任何父事件处理程序被执行stopImmediatePropagation
既能阻止事件向父元素冒泡,也能阻止元素同事件类型的其它监听器被触发。阻止同类型事件在之后绑定的,之前绑定的仍然会触发btn2.addEventListener('click', event => { console.log('btn click 1'); }); btn2.addEventListener('click', event => { console.log('btn click 2'); }); btn.addEventListener('click', event => { console.log('btn click 3'); event.stopImmediatePropagation(); }); btn.addEventListener('click', event => { console.log('btn click 4'); }); VM252:2 btn click 1 VM252:5 btn click 2 VM256:2 btn click 3
- 注意js中绑定回调的情况,先执行回调,再执行默认行为。
所以有时候在回调中直接return false
,实际上做了三件事:event.preventDefault();
event.stopPropagation();
- 停止回调并立即返回。
以上纯属个人理解,如有错误,欢迎指正~