【问题标题】:jQuery .change() event is triggered with .click() in newer versions?jQuery .change() 事件在较新版本中由 .click() 触发?
【发布时间】:2011-06-14 20:06:28
【问题描述】:

我目前正在升级我的应用程序以使用 jQuery 1.6.1(以前使用 1.4.4)并发现现在 .click() 事件也会自动触发 .change() 事件。

我在这里创建了一个简单的例子:http://jsfiddle.net/wDKPN/

请注意,如果您包含 1.4.4,.change() 函数将在触发 .click() 事件时不会触发。但是当切换到 1.6 时,.change() 事件会在.click() 被触发时触发。

两个问题:

  1. 这是一个错误吗?似乎以编程方式触发.click()不应该也触发其他事件(例如,似乎也错误自动触发.blur().focus(),以帮助“模仿”用户的点击)。

  2. 我绑定change() 事件的正确方法是什么然后触发两个该元素的click()change() 事件?我是否只是调用.click(),并依赖.change() 也会触发这一事实?

    $('#myelement').change(function() {
         // do some stuff
    });
    
    $('#myelement').click(); // both click and change will fire, yay!
    

在我的旧代码中,我使用这种模式在 ajax 调用后初始化一些复选框(以及它们的选中状态和值):

    $('#myelement').change(function() {
         // do some stuff including ajax work
    }).click().change();

但在 1.6.1 中,我的逻辑触发了两次(一次用于.click(),一次用于.change())。我是否可以仅依靠删除 .change() 触发器并希望 jQuery 在未来版本中继续以这种方式运行?

【问题讨论】:

  • 尽管这是一个非常好的观察结果,但我将其称为“修复”而不是“错误”。单击复选框使其更改状态,因此它完全有理由触发更改事件。对我来说,奇怪的是它以前没有这样做(并且有a thread on SO)。
  • 当然,我想我可以同意这是故意的,可能不是错误。我希望它在升级时保持这种状态......我们不能为其他事件争论吗?例如,我们是否可以将其改写为“如果用户单击一个复选框,他们必须也已更改它”。我们也可以说,“如果用户点击一个复选框,它必须获得焦点”。但是 .focus() 事件不会像 .change() 那样通过 .click() 自动触发。
  • 有趣的事实,你有没有在 IE(6?)上做了一些测试,因为我记得复选框/jQuery 和事件链的一些奇怪行为?您是否也检查了 triggerHandler('click'),因为文档说“.triggerHandler() 方法不会导致事件的默认行为发生(例如表单提交)”,所以这是否会使链接现在改跑吗?
  • @regilero,我刚刚在 IE7/8/9 中测试过(我现在不关心 6),更糟糕的是,IE7/8 不要使用 jQuery 1.6.1 自动触发 .change() 事件。 IE9 的行为类似于 FF4 / Chrome12 / Safari。因此,至少我们与较低版本的 IE 存在不一致。
  • 我们只是在谈论复选框,对吗?如果您希望单击触发事件,则 SELECT 列表似乎需要绑定到“单击”和“更改”

标签: javascript jquery jquery-click-event


【解决方案1】:

最好的方法是:

$('#myelement').bind('initCheckboxes change', function() {
     // do some stuff including ajax work
}).trigger('initCheckboxes');

要执行初始化工作,您只需将自定义事件绑定到它,您会在页面第一次加载时触发它。这一点,没有人会在任何版本上夺走你。

而我相信,change 事件将继续存在于所有版本中,因为它已经存在了很长时间,而且它只是以这种方式运作良好。

最后,这是一个美好的结局,因为自定义事件 initCheckboxes 只会在页面加载时触发一次,而 change 事件将始终监听并在更改状态时触发。

【讨论】:

  • 太棒了。我对代码太深入了,无法思考大局。这也解决了 IE7/8 的行为与其他所有不同的事实。而且它是升级证明(因此,如果他们决定停止从 .click() 自动调用 .change() 也没关系。最后,在我的 HTML 中,我将创建带有 check="checked" 的复选框,以便在初始化时,它们将被视为“已检查”(这解决了我对下面@kwicher 的评论中的其他要求)。谢谢!
  • triggerHandler 在大多数情况下可能会更好? api.jquery.com/triggerHandlerapi.jquery.com/trigger
【解决方案2】:

我会说这是 jQuery 1.4.4 中的一个错误。删除 jQuery 事件处理程序并使用标准 addEventListener 会产生与 jquery 1.6.1 相同的结果。

http://jsfiddle.net/jruddell/wDKPN/26/

window.count = 0;

document.getElementById('mycheckbox').addEventListener('change', function() {
    window.count++;
    jQuery('#output').append('I fired: ' + window.count + ' times<br />');
});

document.getElementById('mycheckbox').click();

我还会使用triggerHandler 专门调用一个jQuery 事件处理程序。如果您希望事件模型确定要调用哪些处理程序,请使用clickchange 等。

【讨论】:

    【解决方案3】:

    忘记复选框的单击事件。 change 事件处理一切。

    $('#myelement').change(function() {
        // do some stuff
    });
    $('#myelement').trigger('change');
    

    自己看看:http://jsfiddle.net/zupa/UcwdT/ (此演示设置为 jQuery 1.8,但也适用于 1.6。)

    【讨论】:

      【解决方案4】:

      我认为您可以通过将 change() 放在点击处理程序中然后触发点击来使其适用于 jQuery 1.4.4 和 1.6 实现。

      $('.myelement').click(function(){
       $('.myelement').change();   
       alert($(this).val());
      });
      $('.myelement').trigger('click');
      

      看看there的简单例子。

      【讨论】:

      • 这可能适用于我提出的简单用例...但是绑定到 .change() 事件的目的是复选框本身的 state 不同当在 .click() 事件与 .change() 事件中时。我在这里创建了另一个示例:jsfiddle.net/hLVaC/1(请注意,在单击事件中,复选框的实际状态在以编程方式调用时尚未更新,在我的情况下,我使用 ajax 调用来动态确定复选框的选中状态初始化)。
      • 这将无限附加change事件。
      • @Shef - 正确,我刚刚注意到在我的沙盒测试中:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多