1、事件捕获和事件冒泡与事件委托三者的关系
事件冒泡和事件捕获分别由网景公式和微软公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。事件捕获和冒泡是现在浏览器的执行事件的不同阶段,事件委托是利用冒泡阶段的运行机制来实现的
运行条件:当一个事件发生在具有父元素的元素上时,现代浏览器根据事件添加时的设置来执行(冒泡或者捕获)
通过addEventerListener()的第三个参数来设置事件是通过捕获阶段注册的(true),还是冒泡阶段注册的(false),默认情况下是false。
2、 事件冒泡
从实际操作的元素(事件)向父元素一级一级执行下去,直到达到<html>
有的时候父元素和子元素都定义了click事件,但是不希望点击子元素的时候执行父元素的click事件,可以通过阻止冒泡(stopPropagation())在子元素上阻止冒泡。
3、事件捕获
浏览器检查元素的最外层祖先<html>,是否在捕获阶段注册了一个click事件处理程序,如果是,则运行它。
然后,它移动到<html>的下一个元素(点击元素的父元素),并执行相同的操作,然后是下一个元素(点击的元
素的父元素),以此类推,直到达到实际点击的元素。
4、事件捕获和冒泡的区别
执行顺序不同
事件冒泡:事件会从最内层的元素开始发生,一直向上传播,直到document对象。
事件捕获:事件从最外层开始发生,直到最具体的元素。
5、事件委托使用场景
如果你想要在大量子元素中单击任何一个就可以执行一段代码,这个时候可以把事件监听器设置在父节点上。
当事件捕获和事件冒泡同时存在的情况下,事件又是如何触发的呢?
<!--部分HTML代码-->
<div id="s1">father
<div id='s2'>children</div>
</div>
<!--部分JS代码-->
s1.addEventListener("click",function(e){
console.log('father的捕获事件')
},true);
s2.addEventListener("click",function(e){
console.log('children的捕获事件')
},true);
s1.addEventListener("click",function(e){
console.log('father的冒泡事件')
},false);
s2.addEventListener("click",function(e){
console.log('children的冒泡事件')
},false);
打印结果:
father的捕获事件
children的捕获事件
children的冒泡事件
father的冒泡事件
结论:
对于非target节点,则先执行捕获再执行冒泡,对于target节点则先执行先注册的事件,无论冒泡还是捕获。
先执行非target节点的捕获,然后根据注册顺序执行target节点的事件,然后再执行非target节点的冒泡。
addEventerListener,IE8及以下不支持,属于DOM2级的方法,可添加多个方法不被覆盖
解绑事件,参数和绑定相同
removeEventListener(event.type, handle, boolean);
绑定事件兼容IE8及以下
attachEvent(event.type,handle);写事件名时要加上on前缀 ,IE特有,兼容IE8及以下,可添加多个事件处理程序,只支持冒泡阶段
由于事件捕获阶段没有可以阻止事件的函数,所以一般都是设置为事件冒泡
6、阻止冒泡
e.stopPropagation()
stopPropagation是事件对象(Event)的一个方法,作用是阻止目标元素的冒泡事件,但是不会阻止默认行为。
兼容IE
e.cancelBubble = true
阻止冒泡兼容IE写法
window.event?window.event.cancelBubble=true:e.stopPropagation();
e && e.stopPropagation ? e.stopPropagation() : window.event.cancelBubble = true;
7、取消默认事件
e.preventDefault()
preventDefault它也是事件对象的一个方法,作用是取消一个目标元素的默认行为,既然说是默认行为,当然只有它有默认行为才能被取消,如果元素本身无默认行为,调用当然无效啦,比如链接a,提交按钮input type="submit"等,当event对象的cancelable为false时,表示没有默认行为,这时即使有默认行为,调用preventDefault也是不会起作用的。
兼容IE: return false;
js的return false只会阻止默认行为,而是用jquery的话则既可以阻止默认行为,有防止对象冒泡。
8、总结使用方法 :
停止冒泡
function stopBubble(e){
<!--如果提供了事件对象,则这是个非IE浏览器-->
if(e&&e.stopPropagation){
e.stopPropagation();
}else{
<!--我们需要使用IE的方式来取消事件冒泡-->
window.event.cancelBubble = true;
}
}
阻止默认行为
function stopDefault(e){
<!--阻止默认行为W3C-->
if(e&&e.preventDefault()){
e.preventDefault();
}else{
<!--IE中阻止默认行为-->
return false;
}
}
}
9、事件注意点:
1、event代表事件的状态,例如触发event对象的元素,鼠标的位置及状态、按下的键等。
2、event对象只在事件发生的过程中才有效
firefox里的event和IE中的不同,IE里的是全局变量,随时可用,firefox里的要用参数引导才能用,是运行时的临时变量。
在IE/Opera中是window.event,在Firefox中是event;而事件的对象,在IE中是window.event.srcElement,在Firefox中是event.target,Opera中两者都可用。