【问题标题】:How to set a jquery on() function only if it doesn't already existis?仅当 jquery on() 函数尚不存在时,如何设置它?
【发布时间】:2017-05-10 06:48:41
【问题描述】:

我正在通过 ajax 调用附加内容,其中我为单击事件添加了 jquery on() 函数。每次我更新内容时,也会再次设置事件,因此最后会执行多次。如何避免这种行为?

如何测试文档是否已经设置了点击事件?

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<a href="#" class="open-alert">Click</a>
<script>
    // first ajax load
    $(document).on('click', '.open-alert', function () {
        alert('hello world!');
    });

    // second ajax load
    $(document).on('click', '.open-alert', function () {
        alert('hello world!');
    });
</script>

我已经尝试了jQuery.isFunction(),但我不明白如何在这种情况下应用它。

【问题讨论】:

标签: javascript jquery ajax jquery-on


【解决方案1】:

使用

$(document).on('click', '#element_id', function() {
    //your code
});

每次点击时都会检查 DOM 是否匹配元素(通常用于使用 ajax 动态创建的元素)

但是使用

$('#element_id').on('click', function() {
    //your code
});

只会绑定到现有元素。

如果你使用第一个例子,你只需要调用一次,你甚至可以在你的 ajax 调用之前调用它,因为它会在每次点击时重新检查匹配的元素。

<script>
    $(document).on('click', '.open-alert', function () {
        alert('hello world!');
    });

    // first ajax load
    // second ajax load
    ...
</script>

【讨论】:

  • 感谢您的清晰解释。我知道这种差异,但我需要像以前一样调用该事件,因为还有另一个 supajax,否则将不会应用偶数。
  • @wittich 就像我说的 $(document).on('click') 会在每次点击时检查 DOM,你不必调用该事件两次,它可以在任何后续的 ajax 上工作询问。它不会绑定到特定元素,它会在每次点击时在 DOM 上查找元素,因此即使出现新元素,它也会始终有效。
  • 对不起,但我仍然认为您的答案不适合我的问题。我更多地寻找像@saeed-ahmadian-masal这样的答案
【解决方案2】:

如果您执行了多次,您可以取消绑定点击事件。

$(document).unbind('click').on("click", ".open-alert", function () {
  //do stuff here
 });

或者你也可以使用它

$(document).off("click", ".open-alert").on("click", ".open-alert", function () { 

  });

【讨论】:

    【解决方案3】:

    如果您无法将事件绑定到特定的 DOM 元素(例如,如果您使用 Turbolinks 可能会发生这种情况),您可以使用变量来检查您是否设置了事件。

    本地范围

    var clickIsSet = false;
    
    // any ajax load
    $(document).on('click', '.open-alert', function () {
        if ( clickIsSet ) {
            alert('hello world!');
            clickIsSet = true;
        }
    });
    

    全局范围

    我不建议将clickIsSet 全局,但如果您要导入/导出模块,您可以这样做:

    // main.js
    window.clickIsSet = false;
    
    // any-other-module.js
    $(document).on('click', '.open-alert', function () {
        if ( window.clickIsSet ) {
            alert('hello world!');
            window.clickIsSet = true;
        }
    });
    

    【讨论】:

    • 我明白你的想法,但它只允许一个链接,对吧?
    • 如果你想在几个链接元素上使用它,你可以这样做。只需在第二个参数 $(document).on('click', '.first-link, .second-link, .third-link', function () { ... }); 上添加其他类。
    【解决方案4】:

    jQuery 检查元素上是否存在事件:$._data( $(yourSelector)[0], 'events' )

    这会返回所有元素事件,例如:clickblur专注,....

    重要提示:$._data 工作时至少有一个事件绑定到元素

    现在:

    1.在您的主脚本或第一个 ajax 脚本中绑定元素上的点击事件

    <script>
       $(document).on('click', '.open-alert', function () {
          alert('hello world!');
       });
    </script>
    

    2. 在第二个 ajax 中:

    var _data =  $._data( $('.open-alert')[0], 'events' );
    if(typeof _data != "undefined"){
        var eventClick = $._data( $('.open-alert')[0], 'events' ).click
        var hasEventClick = eventClick != null && typeof eventClick != "undefined";
        if(!hasEventClick){
             $(document).on('click', '.open-alert', function () {
                 alert('hello world!');
             });
        }
    }
    

    【讨论】:

    【解决方案5】:

    我对您的问题感到困惑,但据了解您的问题,我有三个建议:

    1. 使用Id元素(如@Mokun write the answer
    2. 为调用功能使用通用函数,而不是通过点击事件使用。(确保函数不会通过调用覆盖您的内容)。
    3. 在 jquery 中使用标志变量(或跟踪事件的全局变量)并识别特定执行的函数调用。

    【讨论】:

      猜你喜欢
      • 2012-10-09
      • 2010-10-22
      • 2013-04-16
      • 2015-10-31
      • 2014-09-05
      • 1970-01-01
      • 2021-08-28
      • 1970-01-01
      • 2017-10-26
      相关资源
      最近更新 更多