【问题标题】:JQuery: Are there any downsides of using only one listener for all buttons?JQuery:对所有按钮只使用一个监听器有什么缺点吗?
【发布时间】:2016-04-17 07:55:56
【问题描述】:

我目前正在研究 tictactoe 的 jquery 实现,以便学习 jquery。在我的 html 中,我定义了九个这样的按钮:

<div class="container">
        <div class="column-center"><button id="1" style="width: 100px; height: 100px"></button></div>
        <div class="column-left"><button id="2" style="width: 100px; height: 100px"></button></div>
        <div class="column-right"><button id="3" style="width: 100px; height: 100px"></button></div>
    </div>
    <div class="container">
        <div class="column-center"><button id="4" style="width: 100px; height: 100px"></button></div>
        <div class="column-left"><button id="5" style="width: 100px; height: 100px"></button></div>
        <div class="column-right"><button id="6" style="width: 100px; height: 100px"></button></div>
    </div>
    <div class="container">
        <div class="column-center"><button id="7" style="width: 100px; height: 100px"></button></div>
        <div class="column-left"><button id="8" style="width: 100px; height: 100px"></button></div>
        <div class="column-right"><button id="9" style="width: 100px; height: 100px"></button></div>
    </div>

在实现 jquery 逻辑时,我认为如果我只为所有这些按钮使用一个侦听器会很好,因为它们都在做同样的事情,我就是这样做的:

    $("button").on('click', function () {
  if(this.id==1||this.id==2||this.id==3||this.id==4||this.id==5||this.id==6||this.id==7||this.id==8||this.id==9){
        $("#"+String(this.id)).css("background-color",$("#color1").css('backgroundColor'));
        $("#"+String(this.id)).prop('disabled', true);
        //all the other logic here...
    }
    else if (this.id==startGame) {
      //start the Game
    }
});

我在这里有三个问题:

  1. 性能比为每个按钮使用一个侦听器更差吗?

  2. 这样实现监听器是一种好习惯吗?

  3. 是否有任何缺点(例如可能发生的一些奇怪的错误)?

【问题讨论】:

  • 查看事件委托和事件冒泡。如果你有很多东西要点击,事件委托可以解决这个问题。
  • 你也可以...$('.container').find('button').on('click', function(e) {...$(document).on('click', '.container button', function(e) :)
  • 做同样的事情。 find 将返回一个 jquery 元素数组并为每个元素绑定一个事件

标签: javascript jquery html performance


【解决方案1】:

性能比为每个按钮使用一个侦听器更差吗?

没有。

这样实现监听器是一种好习惯吗?

没关系,尽管我会将数字按钮与其他按钮分开,因为它们真的不相关。数字按钮的委派可能会更好,并且您的实现中的一些细节可能会改进,但总体概念很好。

是否有任何缺点(例如可能发生一些奇怪的错误)?

不比其他任何事情都如此。


例如,我可能会这样看待它(假设游戏周围有一个没有“开始游戏”按钮的容器):

// Delegation for the number buttons
$("#container-for-the-game").on("click", "button", function () {
    $(this).css("background-color", $("#color1").css('backgroundColor'))
           .prop('disabled', true);
    //all the other logic here...
});
// Start game separately, as it's unrelated
$("#startGame").on("click", function() {
    //start the Game
});

上面有个重要的变化,就是我从

切换
$("#"+String(this.id))

$(this)

注意事项:

  • id 的值已经是字符串,不需要在上面使用String(...)

  • 人们会告诉你不能使用全为数字的id 值。可以,很好,但请注意下一个要点。

  • 从技术上讲,#1 等是无效的 CSS 选择器。 jQuery 可以容忍它们,前提是它们像那样独立运行(作为优化到 getElementById 调用而不是 querySelectorAll 的副产品),但是 CSS ID 选择器不能以未转义的数字开头。虽然$("#1") 工作(与当前的jQuery),$("#1 span") 不会(找到一个span 作为具有id“1”的元素的后代)。最好避免这种习惯。

  • this 已经是被点击的按钮,因此不需要 DOM 查找。

  • 除非您将这些 id 值用于其他用途(我怀疑您可能是),否则您不需要它们。

【讨论】:

  • 我使用了 id 值,例如,当一个新游戏开始时,使用 for 循环启用所有按钮。但是,如果我也将它们称为 button1、button2、...、button9,这将是相同的。那么#button1 会是一个有效的 CSS 选择器吗?
  • @frankenapps:是的。 #1 作为选择器的问题在于它以数字开头。 #button1 很好。
【解决方案2】:

在代码中附加单个侦听器的正确方法是

$('.container').on('click', 'button', listenerFn)

http://api.jquery.com/on/

在这里,您真正创建了一个侦听器来处理您可能添加的所有当前和未来按钮。除了 JQ 必须检查原始目标以匹配选择器这一事实之外,性能没有任何缺点。出于多种原因,这实际上是推荐的方法。

  1. 过多的侦听器会产生内存问题。
  2. 代码更易于维护和阅读
  3. 您可以删除和添加按钮,而无需分离或附加新的事件侦听器

如果您必须更具体地确定要绑定的按钮,请为这些按钮添加一个类,然后在 on 选择器中使用 button.class

希望对你有帮助

【讨论】:

  • “太多的监听器会产生内存问题。” OP 的原版有 one 函数附加到多个元素。上面的开销纯粹是附加它(功能不重复)。使用委托并没有显着改善内存。
  • 考虑到现代浏览器等,你没有“显着”的改进,但你确实得到了一些改进,它本身的功能不是问题是监听器的数量而不是处理程序的数量可能导致如果您运行的是低内存设置,您会遇到性能问题。作为一般规则,避免不必要的听众是个好主意。
【解决方案3】:

像这样附加监听器没有缺点。相反,我觉得它很方便。它使代码更易于管理,您将来能够更轻松地识别和解决错误。

您还可以在按钮中添加 data-dash 属性或类,而不是使用通用按钮标签来附加事件。我认为您的部分代码将来可能会产生错误。

【讨论】:

    猜你喜欢
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 2020-07-30
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    相关资源
    最近更新 更多