【问题标题】:Understanding jQuery .change event了解 jQuery .change 事件
【发布时间】:2018-03-06 08:37:04
【问题描述】:

我在理解 jQuery().change() 行为时遇到了一些问题。

HTML 基本上是很多输入元素 - 复选框(每个 ID 为 id^='o99-post-visible-XXX' - 它们是纯 CSS 图像作为复选框,但这无关紧要),我还有另一个复选框 ("#o99-check-all") 用于“检查all”和一个文本输入字段 ('#o99-post-visible-ids'),用于接收所选框的 ID。

jQuery代码如下:

 jQuery(document).ready(function() {
    jQuery("#o99-check-all").change(function () {
       jQuery("input:checkbox[id^='o99-post-visible-']").prop('checked', jQuery(this).prop("checked")).trigger('change');

    });

        var checkboxes = jQuery("input.o99-cbvu-posts-checkbox:checkbox");
        checkboxes.on('change', function() {
            // get IDS from all selected checkboxes and make a comma separated string
            var ids = checkboxes.filter(':checked').map(function() {
                return this.value;
            }).get().join(',');
            // put IDS inside a text input field
            jQuery('#o99-post-visible-ids').val(ids);
            // console.log(ids);
        });
    });

现在,或多或少现在一切正常,但这不是问题。

起初,第一段代码是:

  jQuery("#o99-check-all").change(function () {
           // without .trigger('change') chained
           jQuery("input:checkbox[id^='o99-post-visible-']").prop('checked', jQuery(this).prop("checked"));

        });

它没有工作(为什么??) - 表示按预期选择了框,但 '#o99-post-visible-ids' 输入字段没有收到 ID - 直到我链接了一个 .trigger('change') 事件 - 突然它工作正常。

我的困惑在于以下(对于我对 jQuery 内部工作的一点了解,这可能是违反直觉的)

在链添加 .trigger('change') 之后 - 这难道不是一个无限循环,其中 chain() 事件在 change() 的侦听器内触发?如果不是,为什么?

为什么代码现在可以正常运行而以前不能正常运行?因为再次,据我了解,即使不是由用户直接点击触发,也会发生变化。为什么需要手动触发?

【问题讨论】:

  • 通过代码检查/取消选中复选框不会引发事件,请参阅jsfiddle.net/wzkr5gtf
  • @Viney - 谢谢,这可以解释它(或多或少像 Bram Vanroy 的回答),但如果 .trigger('change') 确实会引发事件 - 那让我感到困惑的“无限循环”呢?
  • 我没有看到任何循环,触发器被一个一个地调用每个复选框
  • 这可能是我的误解。在第一个块中,.change(function ..() 嵌套了 .trigger('change') 事件。

标签: javascript jquery events onchange


【解决方案1】:

我不确定我明白你的意思。现在发生的事情是,每当你更改all复选框时,其他复选框都会像all一样被选中/取消选中,然后触发change事件.

因为您为change 添加了一个侦听器,所以该函数将触发。 IE。这个函数将运行:

function() {
    // get IDS from all selected checkboxes and make a comma separated string
    var ids = checkboxes.filter(':checked').map(function() {
                  return this.value;
              }).get().join(',');
    // put IDS inside a text input field
    jQuery('#o99-post-visible-ids').val(ids);
    // console.log(ids);
}

没有您的.trigger("change")(或简称.change()),您只能更改输入的属性。所以对象确实发生了变化,但这并不意味着触发了change 事件。听起来确实违反直觉,但事件仅由用户操作或您显式调用事件触发 - 没有其他方式触发事件。

【讨论】:

  • 所以只是为了确认我理解 - 你是说基本上change() 事件只能由用户交互触发,而不是由另一个 jQuery 函数所做的任何其他更改触发。 - 这可以解释它 - 至少在我的脑海中..但是有没有办法以更有效的方式真正倾听这样的事件(由内部函数触发)?因为上面的代码看起来就像一个丑陋的黑客......还有 - 看起来“无限循环”的部分呢
  • 没错。如果您附加了一个侦听器 (.on("change")),则该函数只会由用户交互触发,或者如果您明确调用更改事件。这不是黑客,不用担心。这就是通常的做法。您在哪里看到无限循环?我没看到。你从不在 .on("change") 中调用 .change?
  • 在第一个块中我有.change(function ()..),里面有一个trigger('change')..我知道这不是一个事件而是一个函数..但仍然 - 有点令人困惑..
  • 是的,但是您将它链接到不同的元素。 .change(function())all 复选框上,触发器在其他 div 上。因此,当您在其他复选框上触发更改时,这不会影响 all 复选框。
【解决方案2】:

这是因为您在函数中编写了 jQuery('#o99-post-visible-ids').val(ids);,该函数仅在输入上完成更改事件时发生,直接通过 .prop 分配 prop 不会触发 change 事件,因此结果处理程序不会运行

【讨论】:

    【解决方案3】:

    如果我理解正确的话……

    ...因为您要为每个复选框提供相同的 ID?如果您希望将其应用于多个元素,最好使用类选择器

    jQuery(".o99-check-all").change(function () {
    // without .trigger('change') chained
    jQuery(".o99-check-all").prop('checked', jQuery(this).prop("checked"));
    });
    

    查看链接 https://api.jquery.com/change/

    【讨论】:

    • 好吧 - 要么我误解了答案,要么实际上你理解错误 - ID 仅适用于 ONE "check - all" 复选框(可能是我的错 - 我可能应该包含标记 - 但我很害怕会太长)
    • 您不必添加任何东西。只需按类参考即可。如果您通过 ID 引用它,它将导致所有类型的模棱两可的错误。我还添加了指向 JQuery 更改事件处理程序的链接以澄清更多信息。
    • 如果我按类引用它,我怎么能收集IDS(这是最终目标)。你的意思是只按类收集对象吗?
    猜你喜欢
    • 2017-10-07
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 2013-11-25
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多