资讯专栏INFORMATION COLUMN

阻止事件传播

chanthuang / 2112人阅读

摘要:和下面的代码完全等价阻止默认事件阻止传播但是如果页面中有,你在它的父元素任何一层,包括自己,添加了组织默认事件那么这个就没办法被。

上一次学习了DOM 的事件,理解了冒泡事件和捕获事件,触发的机制,今天学习一下具体的应用场景,或者说在哪个地方容易踩坑。

做一个小demo,点击按钮出现浮层,点击其它地方关闭浮层,写一个简单css


浮层

那现在我要点击页面空白地方关闭呢?该用什么方法,很容易想到监听文档,如下代码

document.addEventListener("click",function(){
    popover.stely.display = "none";
});

但是实际上这样写了之后,按钮都失效了,怎么点都没有反应。这是为什么呢?
理解上一篇讲的捕获和冒泡事件后就很好理解这点了,可以DOM事件之捕获、冒泡。
我们没有指定监听是在捕获还是冒泡阶段,浏览器默认是冒泡阶段,当我们点击按钮时,捕获阶段没有发生什么时候,但是冒泡阶段就不一样了,首先button上函数先触发,然后document上函数也触发了,导致准备出现的浮层又被隐藏了。
那你可能要问,button上的事件执行了没?其实这两个事件都执行了,只是时间太短,浏览器默认一起执行了,可以在里面加一个debugger,就可以看到了。

clickMe.addEventListener("click",function(){
    popover.style.display = "block";
});

那该怎么解决呢?最简单的方法是,除了要执行popover.style.display = "block",还要阻止事件传播

clickMe.addEventlistener("click",function(){
    popover.style.display = "block";
});

popover.addEventListener("click",function(e){
    e.stopPropagation();
});

这里为什么添加在按钮的父元素上面呢?如果不添加在父元素上面,点击浮层的时候,浮层也会被关闭。

如果页面上有很多监听器的话,这个方法是比较浪费内存的,比较省内存的方法用JQuery 做

$(clickMe).on("click",function(){
    $(popover).show();
    $(document).one("click",function(){
        $(popover).hide();
    });
});
$(wrapper).on("click",function(e){
    e.stopPropagation();    
})

一开始不监听,只在popover`show`的时候监听一次,马上关掉,这叫做清理战场。
$(wrapper).on("click",false) 和下面的代码完全等价

$(wrapper).on("click",function(e){
    e.preventDefault();     //阻止默认事件
    e.stopPropagation();    //阻止传播
})

但是如果页面中有checkbox,你在它的父元素任何一层,包括checkbox自己,添加了组织默认事件那么这个checkbox就没办法被check

这里有个问题,如果没有阻止事件传播,向下面这样,会发生什么事情呢?

$(clickMe).on("click",function(){
    $(popover).show();
    $(document).one("click",funtion(){
        $(popover).hide();
    });
});

当然了,和之前一样,什么事情也不会发生,那当我点击按钮之后里面都发生了那些事情呢?
当我点击了按钮之后,它会做两件事情,首先把popover`show出来,然后把hide函数添加到document上面,当事件传播到document`,就会又把它给隐藏了。

可以给它添加一个setTimeout()函数来解决这个问题

$(clickMe).on("click",function(){
    $(popover).show();
    setTimeout(function(){
        $(document).one("click",function(){
            $(popover).hide();
        })
    },0)
});

setTimeout(fn,0)这个0不是马上执行,而是尽快执行,具体是在冒泡结束在执行这里的函数,也就是说,当冒泡结束后,在把监听事件添加到document上面,等待用户下次点击在执行。

用 jQuery 做事件冒泡


总结:

同时监听buttondocument,点啥都没反应,因为两个函数都执行了,用阻止事件传播解决了,比较浪费内存

好一定的方法是用jQuery 做,点击button后在监听document,关闭了就不再监听,不阻止事件传播,点啥也没反应,两种解决方法:一种是阻止事件传播,另一种是添加一个setTimeout()函数。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95225.html

相关文章

  • 浏览器事件模型中捕获阶段、目标阶段、冒泡阶段实例详解

    摘要:目标阶段真正点击的元素的事件发生了两次,因为在上面的代码中,既在捕获阶段绑定了事件,又在冒泡阶段绑定了事件,所以发生了两次。所以很明显用直接绑定的事件发生在了冒泡阶段。 如果对事件大概了解,可能知道有事件冒泡这回事,但是冒泡、捕获、传播这些机制可能还没有深入的研究实践一下,我抽时间整理了一下相关的知识。 本文主要对事件机制一些细节进行讨论,过于基础的事件绑定知识方法没有介绍。 特别少...

    mylxsw 评论0 收藏0
  • JS DOM Event

    摘要:事件处理程序事件侦听器的设定级级首先讲级事件处理程序对事件的方式被称为事件处理程序或事件侦听器,但这两者之间是有区别的。此外,不能对事件目标事件类型执行阶段都相同的对象注册多个相同的事件侦听器。 关于这一篇章有太多对于我来说杂且乱的知识点,单单是分别DOM层级划分我看过的文章就有(0,2,3)的,(0,2)的,由于自己知识掌握还很薄弱所以只能参考别人文章结合自己理解来写,这其中也涉及到...

    WelliJhon 评论0 收藏0
  • Javascript事件

    摘要:见下图更直观在事件流中,事件的目标在捕获阶段不会接受到事件,这意味着在捕获阶段,事件从到后就停止了。下一个阶段是目标阶段,于是事件在上发生,并在事件处理中被看成是冒泡阶段的一部分,然后,冒泡阶段发生,事件又传回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕获 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是从页面中接受事件的顺序 2.DOM事件流的三个阶...

    baiy 评论0 收藏0
  • Javascript事件

    摘要:见下图更直观在事件流中,事件的目标在捕获阶段不会接受到事件,这意味着在捕获阶段,事件从到后就停止了。下一个阶段是目标阶段,于是事件在上发生,并在事件处理中被看成是冒泡阶段的一部分,然后,冒泡阶段发生,事件又传回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕获 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是从页面中接受事件的顺序 2.DOM事件流的三个阶...

    luffyZh 评论0 收藏0
  • Javascript事件

    摘要:见下图更直观在事件流中,事件的目标在捕获阶段不会接受到事件,这意味着在捕获阶段,事件从到后就停止了。下一个阶段是目标阶段,于是事件在上发生,并在事件处理中被看成是冒泡阶段的一部分,然后,冒泡阶段发生,事件又传回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕获 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是从页面中接受事件的顺序 2.DOM事件流的三个阶...

    pcChao 评论0 收藏0

发表评论

0条评论

chanthuang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<