DOM事件存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
事件捕获:通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件。
事件冒泡:与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点
dom标准事件流的触发的先后顺序为:先捕获再冒泡,即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。
添加事件监听
1、addEventListener()方法特点:
element.addEventListener(event, function, useCapture)中的第三个参数可以控制指定事件是否在捕获或冒泡阶段执行。true - 事件句柄在捕获阶段执行。false- 默认- 事件句柄在冒泡阶段执行。
addEventListener() 可以给同一个元素绑定多个事件,不会发生覆盖的情况。如果给同一个元素绑定多个事件,那么采用先绑定先执行的规则。
addEventListener() 在绑定事件的时候,事件名称之前不需带 on 。
可以使用 removeEventListener() 来移除之前绑定过的事件。
2、attachEvent()方法特点:
attachEvent是 IE 有的方法,它不遵循W3C标准,而其他的主流浏览器如FF等遵循W3C标准的浏览器都使用addEventListener,所以实际开发中需分开处理。
attachEvent()是 后绑定先执行。
绑定时间时,attachEvent必须带 on
detachEvent移除之前绑定过的事件
事件捕获
html
<div class="outer">
<div class="inner"></div>
</div>
绑定事件监听
document.getElementById("parent").addEventListener("click",function(e){
alert("outer事件被触发");
})
document.getElementById("child").addEventListener("click",function(e){
alert("inner事件被触")
})
结果
inner事件被触发
outer事件被触发
结论:先inner然后outer。事件触发顺序变更为自内向外,这就是事件冒泡。
document.getElementById("parent").addEventListener("click",function(e){
alert("outer事件被触发");
},true)
document.getElementById("child").addEventListener("click",function(e){
alert("inner事件被触发")
},true)
结果
outer事件被触发
inner事件被触发
结论:先outer,然后inner。事件触发顺序变更为自外向内,这就是事件捕获。
总结
true,事件捕获;false,事件冒泡。默认false,即事件冒泡
事件监听的兼容性写法
//添加事件
//domobj例如btn哦,eventType例如onclick,fn函数名
function addEvent(DOMobj,eventType,fn){
if(DOMobj.addEventListener){
DOMobj.addEventListener(eventType,fnName,false)
}else{
DOMobj.attachEvent("on"+eventType,fn);//兼容
}
}
//移除事件
function removeEvent(DOMobj,eventType,fn){
if(DOMobj.removeEventListener){
DOMobj.removeEventListener(eventType,fnName,false)
}else{
DOMobj.detachEvent("on"+eventType,fn);//兼容
}
}
阻止事件冒泡的兼容写法
if(evt.stopPropagation){
evt.stopPropagation();
}else{
evt.cancelBubble==true;
}