禁用元素的停止事件冒泡

Posted

技术标签:

【中文标题】禁用元素的停止事件冒泡【英文标题】:Stop Event bubbling for a disabled element 【发布时间】:2013-09-29 22:37:02 【问题描述】:

我有一个有样式的按钮

pointer-events: none;

并且这个按钮有一个执行折叠事件的父元素。我不知道如何防止此按钮触发其父元素可折叠事件。这是因为按钮样式是指针事件:无

谢谢

【问题讨论】:

如果您向我们展示 html,那么我们可能会提供帮助 :) pointer-events 不是禁用元素的方法,它只是取消所有指针事件,并且对您正在做的事情需要底层元素上的指针事件很有帮助。 你需要 e.stopPropagation() @adeneo - 是的,我需要指针事件来防止该元素上的指针事件。但是,当用户单击此元素时,它会触发其父元素的操作,而我不想这样做。 如果您确定自己知道什么是指针事件以及如何使用它们,那很好,但听起来指针事件并不是您所需要的。无论如何,在父元素的事件处理程序中,只需执行e.target === this 检查,或停止传播,但我不确定这是否适用于没有指针事件的元素,当单击这样的元素时,你真正点击它,所以你很可能正在点击父元素,至少如果该元素在没有指针事件的元素“后面”,因为这就是重点。 【参考方案1】:

假设以下html:

<div class="collapsible">
    <button>Hi</button>
</div>

你可以这样做:

$('.collapsible').click(function(e) 
    if ($(this).children('button').css('pointer-events') == 'none') return;

    //do collapse
);

或者可能是这样的:

$('.collapsible').click(function(e)         
    //do collapse
);

$('.collapsible button').click(function(e) 
   if ($(this).css('pointer-events') == 'none')
       e.stopPropagation();
);

【讨论】:

带有pointer-events:none 的元素不会触发事件处理程序【参考方案2】:

正如@adeneo 所说,如果您在孩子上使用pointer-events: none,那么父母的事件侦听器无法知道目标是它自己还是它的孩子。 这就像当您单击段落中的某些文本时,事件侦听器无法知道您是否单击了文本或段落的填充。

然后,你可以使用

document.getElementById('outer').onclick = function(e) 
    /* your code */
;
document.getElementById('outer').addEventListener('click',  function(e) 
    if(e.target !== this) 
        e.stopPropagation();
    
, true);

没有pointer-events: none

这样,您使用捕获阶段,因此您可以阻止执行子事件处理程序(如pointer-events: none),但现在您可以区分用户是否单击了您的元素或其子元素。

Demo jsFiddle

问题:您不能在旧版本的 IE 上使用捕获阶段。

优点:由于不能在旧版IE上运行,所以不用担心

e = e || window.event e.target || e.srcElement if (e.stopPropagation) e.stopPropagation(); else e.calcelBubble=true;

【讨论】:

以上是关于禁用元素的停止事件冒泡的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义事件中停止事件传播/冒泡

jquery事件冒泡

停止 jQuery Mobile 滑动事件双冒泡

jQuery事件冒泡及解决办法

jq事件冒泡问题

停止事件冒泡 - 提高性能?