参考资料
事件冒泡
微软提出,嵌套元素触发事件,从内向外执行代码
在p元素上发生click事件的顺序应该是==p -> div -> body -> html -> document==
<div id="s1">s1
<div id="s2">s2</div>
</div>
<script>
// 点击s1 - s1 冒泡事件
// 点击s2 - s2 冒泡事件 s1 冒泡事件
s1.addEventListener("click",function(e){
console.log("s1 冒泡事件");
},false);
s2.addEventListener("click",function(e){
console.log("s2 冒泡事件");
},false);
</script>
事件捕获
网景公司提出,嵌套元素触发事件,从外层开始直到具体元素
在p元素上发生click事件的顺序应该是==document -> html -> body -> div -> p==
<div id="s1">s1
<div id="s2">s2</div>
</div>
<script>
// 点击s1 - s1 捕获事件
// 点击s2 - s1 捕获事件 s2 捕获事件
s1.addEventListener("click",function(e){
console.log("s1 捕获事件");
},true);
s2.addEventListener("click",function(e){
console.log("s2 捕获事件");
},true);
</script>
!!!w3c规定先捕获再冒泡
addEventListener(event, callback, useCapture)
- 第一个参数是需要绑定的事件
- 第二个参数是触发事件后要执行的函数
- 第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。
如果冒泡和捕获同时存在?
- 对于非target节点则先执行捕获在执行冒泡
- 对于target节点则是先执行先注册的事件,无论冒泡还是捕获
<div id="s1">s1
<div id="s2">s2</div>
</div>
<script>
// 事件冒泡
// 点击s1 s1 冒泡事件 s1 捕获事件 (按照注册顺序)
// 点击s2 s1 捕获事件 s2 冒泡事件 s2 捕获事件 s1 冒泡事件
s1.addEventListener("click",function(e){
console.log("s1 冒泡事件");
},false);
s2.addEventListener("click",function(e){
console.log("s2 冒泡事件");
},false);
// 事件捕获
s1.addEventListener("click",function(e){
console.log("s1 捕获事件");
},true);
s2.addEventListener("click",function(e){
console.log("s2 捕获事件");
阻止事件冒泡
- e.stopPropagation() 【非ie】
- e.cancelBubble = true 【ie】
阻止默认事件
- e.preventDefault() 【谷歌及IE8以上】
- window.event.returnValue = false 【IE8以下无兼容问题(但不能用于节点直接onclick绑定函数)】
- return false;
事件委托
事件委托也称为事件代理利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
/**
* @param eventType:String,事件类型
* @param element:DOM element,目标元素
* @param callback:Function,业务事件处理程序
*/
function eventHandler(eventType, element, callback) {
document.addEventListener(eventType, function(e){
if(e.target === element) {
callback.call(this);
}
}, false);
}
评论区