7

我最近在与一位同事讨论我们的编码实践中的一些差异,在那里我提出了一个关于他在他的事件处理程序中过度使用上述两种方法的问题。具体来说,它们看起来都是这样的......

$('span.whatever').on('click', function(e) {

    e.preventDefault();
    e.stopPropagation();

    /* do things */

});

他声称这是一个很好的实践,没有可预见的反弹,并且将改善跨平台支持,同时减少未来的意外问题。

我对你们的问题:如果他是对的,为什么 jQuery 团队没有将这种行为全局应用于所有事件处理程序?实际上,我的假设是他错了,仅仅是因为这些方法可以独立使用,但谁知道……非常感谢您的洞察力。

--

更新:我做了一个简单的速度测试,这两个功能造成了一点阻力,但没有什么特别明显的。不过,除其他外,我认为在使用它们时要慎重考虑是一个很好的理由。

$('span.whatever').on('click', function(e) {

    var start = new Date();

    for (i = 0; i < 999999; i++) {
        e.preventDefault();
        e.stopPropagation();
    }

    console.log( new Date() - start );

});

上面记录了约 9.5 秒,当我将函数调用退出循环时,约 2.5 秒。

4

3 回答 3

9

我没有和你的同事做同样的事情(在每个事件处理程序上推送 2 个调用),但我确实有同样的做法,即明确使用这些调用而不是“返回 false;”,我相信这让我生活更轻松。

当我开始使用 Jquery 时,我想如果我需要停止传播并防止默认值,我应该只“返回 false”,我到处都这样做了。

$('a.whatever').on('click', function(e) {

    do_stuff();

    return false;
}); 

但是我最终遇到了两个问题:

  • 如果 do_stuff() 有任何导致异常的严重错误,“return false;” 永远都达不到!!!错误最终会被 jquery “很好地” 吞下;您的事件将冒泡,并让浏览器执行默认操作。如果您在一个单页应用程序中并且单击了一个链接,那么据您所知,该页面已导航离开,并且整个应用程序状态都消失了(我以前去过那里)。

  • 我对返回 false 太宽容了:在很多情况下,我只需要一个 preventdefault()。“return false”正在扼杀事件冒泡,有时会阻碍我执行更高 dom 层次结构的另一个操作的能力(或者使我使用的其他一些插件/库无法正常工作)

所以我现在更喜欢明确。我几乎从不使用“return false;” 不再。如果我有一个不能传播或不执行默认值的事件处理程序,我会故意将它放在我的函数FIRST中,在任何处理代码之前。在事件处理期间发生的任何事情都不应影响我不希望默认操作运行和/或事件不冒泡的事实。

是的,话虽如此,我也注意到在需要时只使用这两个中的一个(或者在某些情况下根本不使用)。我不会无缘无故地同时添加 preventDefault() 和 stopPropagation() 。我在处理程序中操纵事件的任何地方,都是有意识的逐案决策的一部分。

于 2013-03-08T02:15:07.447 回答
0

如果元素是菜单的一部分并且单击事件应该冒泡并告诉菜单也自行关闭,那将是一个问题。

或者,如果菜单在其他地方打开并且在菜单外部单击应该会冒泡到事件处理程序将关闭菜单的主体。但是停止气泡的元素会阻止菜单关闭。

于 2013-03-08T02:16:28.493 回答
0
<div id="wrapper">
            <div id="header">header
              <div id="footer">footer
              <div id="content">click this!!!</div>
              </div>
            </div>


        </div>


$("#wrapper div").click(function(){
  console.log(  $(this) )
});

请尝试单击到 div 并显示控制台...

现在添加

$("#wrapper div").click(function(e){
  e.stopPropagation()
})
于 2016-01-04T09:47:26.533 回答