【问题标题】:Jquery Event bound twice after ajax callajax调用后Jquery Event绑定两次
【发布时间】:2018-08-21 07:33:47
【问题描述】:

我想在由 ajax 调用动态创建的元素上绑定一个事件。 一些元素已经存在,并且在页面加载时与它们绑定了一个事件。但是当在 ajax 调用之后创建新元素时,新元素会失去它们的绑定。

我搜索并找到了一个非常好的解决方案。 Jquery Event won't fire after ajax call

在这个问题中,“Jason Fingar”提出了两种解决方案来解决这个问题

  • 第二种解决方案是使用 on 方法,但它对我不起作用
  • 第一种方法可行,但存在一些问题

这是他提出的第一个解决方案

"1) 封装您的“绑定”代码,并在页面加载时以及相关元素添加回页面后立即调用它。例如:"

$(document).ready(function(){
// bind event handlers when the page loads.
bindButtonClick();
});

function bindButtonClick(){
$('.myClickableElement').click(function(){
    ... event handler code ...
});
}

function updateContent(){
$.ajax({
    url : '/ajax-endpoint.php',
    data : {'onMyWay' : 'toServer'},
    dataType : 'html',
    type : 'post',
    success : function(responseHtml){
        // .myClickableElement is replaced with new (unbound) html 
     element(s)
        $('#container').html(responseHtml);

        // re-bind event handlers to '.myClickableElement'
        bindButtonClick();  
    }
});
}

我面临什么问题? 该事件与新元素绑定成功,但对于旧元素或页面加载时加载的元素,事件被绑定两次。 这有什么问题?

【问题讨论】:

    标签: javascript jquery ajax jquery-events


    【解决方案1】:

    在为同一事件绑定侦听器之前,jQuery 不会检查事件侦听器是否已经绑定到元素。在您的代码中,.myClickableElement 选择所有此类元素,并且对于现有元素,将添加重复的侦听器。

    首先解除绑定事件监听器

    解决此问题的一种方法是先删除侦听器,然后再次绑定它。这样每个目标元素都会存在一次。

    function bindButtonClick(){
      $('.myClickableElement').off('click').on('click', function(){
        ... event handler code ...
      });
    }
    

    通过在父元素上使用事件委托

    另一种(但有效的)方法是对子元素使用事件委托。我不太了解您的 HTML,但您可以在父元素上执行此操作(.parent 这里是所有 .myClickableElement 元素的父元素):

    $('.parent').on('click', '.myClickableElement', function() {
      ... event handler code ...
    });
    

    这也将为这些元素启用事件绑定,这些元素在此代码执行时不存在于 DOM 中。因此,这将是您问题的通用解决方案,并且您无需在 AJAX 完成时绑定侦听器。

    【讨论】:

      【解决方案2】:

      您可以使用document.on 或父容器委托 cilck 事件,这将适用于现有以及动态创建的元素,无需在 ajax 调用内部一次又一次地绑定它

      $(document).ready(function(){
         // If you know that elements for which click handler required can be anywhere in the document
         /*$(document).on('click', '.myClickableElement', function(){
          ... event handler code ...
         });*/
      
         //If you are sure that elements to which click event handler required is belongs to container elements
         $('#container').on('click', '.myClickableElement', function(){
          ... event handler code ...
         });
      });
      
      function updateContent(){
      $.ajax({
          url : '/ajax-endpoint.php',
          data : {'onMyWay' : 'toServer'},
          dataType : 'html',
          type : 'post',
          success : function(responseHtml){
              // .myClickableElement is replaced with new (unbound) html 
           element(s)
              $('#container').html(responseHtml);
      
              // re-bind event handlers to '.myClickableElement'
              //bindButtonClick();   -- not required to bind again
          }
      });
      }
      

      【讨论】:

        【解决方案3】:

        您必须使用 unbind 方法取消绑定为您的元素委派的事件,然后重新绑定它。

        $('.myClickableElement').unbind('click').bind('click', function(){
            // action goes here
        });
        

        如果您的.myClickableElement 已经有一个附加事件,您可以通过取消绑定来删除它。

        如需更好的方法,请查看documentation

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-02-03
          • 2011-06-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-07
          相关资源
          最近更新 更多