事件冒泡与事件捕获
- 事件冒泡与事件捕获:与标签嵌套有关系(文档树),与实际视图的位置(呈现树)无关。假如标签是父子关系,而我们在设置css样式时,在界面用定位两者并没有重合部分,但是他们仍然因为是父子关系,存在事件冒泡与事件捕获。
- 事件捕获:事件从最不精确的对象开始触发,然后到最精确的对象。
- 事件冒泡:顶层对象是windows。事件按照从最特定的事件目标到最不特定的事件对象的顺序触发。如果事件发生了,在捕获阶段没有处理,冒泡阶段也没有人处理,由于垃圾回收机制这个事件就消失。
具体过程如下:
例子:
document.querySelector(".father").addEventListener("click",function() {
console.log("父元素")
},false)
document.querySelector(".son").addEventListener("click",function() {
console.log("子元素")
})
- 首先我们先了解事件绑定函数的第三个参数为true或false的区别。当第三个参数为false时,即为事件绑定函数的默认值时,事件在冒泡过程中触发。当第三个参数为true时,事件在捕获过程中触发。
- 我们假设视图中的div是父元素,text是子元素。
- 当我们点击父元素时:结果打印父元素。正如上图所示:当我们点击父元素时,我们在父元素冒泡中执行了父元素的事件。执行顺序为:1-2-3-4-7-8-9-10,父元素事件在7这里执行。
- 当我们点击子元素:结果打印子元素->父元素。正如上图所示:当我们点击子元素时,执行顺序为1-2-3-4-5-6-7-8-9-10.子元素在第6步执行事件,父元素在第7步执行事件。
- 假设我们想点击子元素时,结果打印父元素->子元素这样的顺序,我们可以将代码改为
document.querySelector(".father").addEventListener("click",function() {
console.log("父元素")
},true)
document.querySelector(".son").addEventListener("click",function() {
console.log("子元素")
})
执行顺序为:1-2-3-4-7-8-9-10,父元素事件在4这里执行,子元素事件在6这里执行。
阻止事件冒泡的方法
- 当我们想对某一具体元素触发事件时,事件冒泡往往会触发其父元素的事件,影响我们实际需求开发。
- ①IE8以上的版本和现代浏览器:e.stopPropagation()
document.querySelector(".father").addEventListener("click",function() {
console.log("父元素")
},false)
document.querySelector(".son").addEventListener("click",function(e) {
console.log("子元素")
e.stopPropagation()
})
当我们点击子元素:结果打印子元素。
- ②支持该方法的浏览器中也可以用stopImmediatePropagation()方法,这个不仅会阻止事件向父元素的冒泡,也会阻止同一个节点上同一事件的其他的事件处理程序(优先级比它低)
document.querySelector(".father").addEventListener("click",function() {
console.log("父元素")
},false)
document.querySelector(".son").addEventListener("click",function(e) {
console.log("子元素业务1")
e.stopImmediatePropagation()
})
document.querySelector(".son").addEventListener("click",function(e) {
console.log("子元素业务2")
})
当我们点击子元素:结果打印子元素业务1。
//同一对象绑定两次onclick,第一个加这个方法:第二个处理函数不会执行
//同一对象绑定两次onclick,第二个加这个方法:两个处理函数都会执行
- ③在IE8以及IE以下的浏览器:e.cancleBubble=true
阻止默认事件
- a标签默认事件跳转页面,表单默认提交事件等。
- 当我们需要组织默认事件时,采用e.preventDefault()方法
<a href="www.baidu.com" id="ahref">点击</a>
<form action="/test" method="post">
<input type="password" name="" />
<input type="submit" value="xxxxx"/>
</form>
ahref.addEventListener("click",function(e) {
console.log(点击了a标签)
e.preventDefault()
})