过度使用jQuery的preventDefault()和stopPropagation()

时间:2013-03-08 01:44:31

标签: javascript jquery

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

$('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秒。

3 个答案:

答案 0 :(得分:9)

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

当我开始使用Jquery时,我想我是否需要停止传播并防止默认,我应该“返回false”,我在那里做了很多。

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

    do_stuff();

    return false;
}); 

但是我偶然遇到了两个问题:

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

  • 我对自己的回报过于宽容:在很多情况下,我只需要一个preventdefault()。 “return false”是杀死事件冒泡,有时会阻碍我在dom层次结构中执行另一个操作的能力(或者使我使用的其他一些插件/库不能正常工作)

所以我现在更愿意明确。我懒洋洋地从不使用“return false;”更多。如果我有一个必须不传播或不执行默认值的事件处理程序,我会在任何处理代码之前将其添加到我的函数 FIRST 中。无论在事件处理过程中发生什么, NOT 都会影响我不希望默认操作运行和/或事件不起泡的事实。

是的,据说,我也注意在需要时只使用其中一个(或者在某些情况下根本不使用)。我不会无缘无故地添加preventDefault()和stopPropagation()。无论我在处理程序中操纵一个事件,它都是有意识的逐案决策的一部分。

答案 1 :(得分:0)

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

或者,如果某个菜单在其他地方打开并且在菜单外面点击,则该菜单应该冒泡到正文,事件处理程序会关闭菜单。但是已停止泡泡的元素阻止菜单关闭。

答案 2 :(得分: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()
})