js事件捕获或和事件冒泡

js的事件捕获和事件冒泡发生在dom节点绑定事件触发的过程中,事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。相反的,事件冒泡是自下而上的去触发事件,事件捕获和事件冒泡属于两个相反的过程。

一般的,事件分为三个阶段:捕获阶段、目标阶段和冒泡阶段。

(1)捕获阶段

事件从文档的根节点流向目标对象节点,途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。

(2)目标阶段
当事件到达目标节点时,事件在目标节点上被触发,然后会逆向回流,直到传播至最外层的根节点。
(3)冒泡阶段
事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播。

示例代码:

<!DOCTYPE html>
<html>
<head>
    <title>event</title>
</head>
<body>
<div id="obj1">
    welcome
    <h5 id="obj2">hello</h5>
    <h5 id="obj3">world</h5>
</div>
<script type="text/javascript">
    var obj1=document.getElementById('obj1');
    var obj2=document.getElementById('obj2');
    obj1.addEventListener('click',function(){
        alert('hello');
    },false);
    obj2.addEventListener('click',function(){
        alert('world');
    })
</script>
</body>
</html>
如上所示,这是一个十分简单地文档结构:document > html > body > div > h5 

1,点击文字welcome时,弹出hello。 
此时就只触发了绑定在obj1上的点击事件。具体冒泡实现过程如下:welcome 属于文本节点,点击后,开始从文本节点查找,当前文本节点没有绑定点击事件,继续向上找,找到父级(id为obj1的div),有绑定的点击事件,执行,再向上找,body,没有绑定点击事件,再到html,document,都没再有绑定的点击事件,整个冒泡过程结束。

2,点击文字hello时,先弹出world,再弹出hello。

具体冒泡过程如下:

文本hello --->id为obj2的h5  ---->id为obj1的div  ---> body ---> html --->document

3,点击world时,弹出hello。 

具体冒泡过程如下:

文本world --->id为obj3的h5  ---->id为obj1的div  ---> body ---> html --->document


阻止事件冒泡和捕获

做为一个web开发者,你可以选择是在捕获阶段还是冒泡阶段绑定事件处理函数,这是通过addEventListener()方法实现的,如果这个函数的最后一个参数是true,则在捕获阶段绑定函数,反之false,在冒泡阶段绑定函数。

element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)
制作的网页中,没有必要让一个事件因为冒泡而被好几个函数处理。但是有时用户通常会很疑惑,因为在他们只点击了一次鼠标之后出现了许多种情况(多个函数被执行,因为冒泡)。而大多数情况下你还是希望你的处理函数相互独立的。当用户点击了某一个元素,发生什么,点击另一个元素,又对应发生些什么,相互独立,而不因为冒泡连锁。

一般情况下,你会想关了所有的冒泡和捕获以保证函数之间不会打扰到对方。除此之外,如果你的文档结构相当的复杂(许多table之间相互嵌套或者诸如此类),你也会为了节省系统资源,而关闭冒泡。此时浏览器不得不检查目标元素的每一个祖先,看是否它有一个处理函数。即使一个都没有找到,搜索同样花费不少时间。

在微软的模型中,你必须设置事件的cancelBubble的属性为true

window.event.cancelBubble = true
在w3c模型中你必须调用事件的stopPropagation()方法

document.getElementById("button").addEventListener("click",function(event){
    alert("button");
    event.stopPropagation();
},false);
 stopPropagation()方法既可以阻止事件冒泡,也可以阻止事件捕获,也可以阻止处于目标阶段。

我们也可以使用DOM3级新增事件stopImmediatePropagation()方法来阻止事件捕获,另外此方法还可以阻止事件冒泡。

document.getElementById("second").addEventListener("click",function(){
    alert("second");
    event.stopImmediatePropagation();
},true);
这样,就可以在id为second处阻止事件的捕获了。

stopImmediatePropagation() 和 stopPropagation()的区别在于:后者只会阻止冒泡或者是捕获。 但是前者除此之外还会阻止该元素的其他事件发生,但是后者就不会阻止其他事件的发生。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值