【问题标题】:Callbacks running twice after AJAX content loaded加载 AJAX 内容后回调运行两次
【发布时间】:2013-04-29 18:14:48
【问题描述】:

我有一个带有航点无限滚动插件的页面加载内容。

在 AJAX 调用成功并添加 DOM 元素后,将运行回调以重新初始化 javascript 功能,如轮播、按钮和其他动画。

在第一次 AJAX 调用中,负责切换的按钮可以正常工作。在下一次 AJAX 调用中,新的 DOM 项工作,但之前的按钮现在在单击时执行两次切换。在第三次调用中,原始项目现在运行 3 次,第二个项目运行两次,新项目运行一次,依此类推,第四次,在调用 AJAX 内容时继续复合。

如何隔离回调不影响之前加载的内容,或者,有没有办法给JS设置一个全局状态,这样就不用每次都需要回调了?

一些伪代码:

$('.infinite-container').waypoint('infinite', {

    onAfterPageLoad: function() { 

        //Carousel options     
        $('.carousel-container').carousel({
            options: here,
            ....
        }); 

        //Button Toggles
        $('.button').click(function(){

            var self = $(this); 

            $(this).siblings('.caption').animate({ 

               height: 'toggle'

               }, 200, function() {

                 // Callback after animate() completes.
                 if(self.text() == 'Hide Details'){

                   self.text('Show Details');

                 } else {

                   self.text('Hide Details');
                 }
            }); 
        }); 

     }   
});    

编辑:谢谢大家。所有的答案都让我找到了不同但合适的解决方案。选择的内容是所有建议问题的精彩集合,值得一读。

【问题讨论】:

    标签: javascript jquery ajax infinite-scroll jquery-waypoints


    【解决方案1】:

    看看这个答案。我认为这与您遇到的情况相同并且有解决方案:

    Best way to remove an event handler in jQuery?

    【讨论】:

      【解决方案2】:

      每次执行该代码块时,您都会附加一个新的单击处理程序。结果是多个单击处理程序绑定到您的按钮。使用 jQuery 的 unbind: http://api.jquery.com/unbind/ 删除任何点击处理程序,然后再添加一个新的:

      $('.infinite-container').waypoint('infinite', {
      
          onAfterPageLoad: function() { 
      
              //Carousel options     
              $('.carousel-container').carousel({
                  options: here,
                  ....
              }); 
      
              // Un-bind click handler(s)
              $('.button').unbind('click');
      
              //Button Toggles
              $('.button').click(function(){
      
                  var self = $(this); 
      
                  $(this).siblings('.caption').animate({ 
      
                     height: 'toggle'
      
                     }, 200, function() {
      
                       // Callback after animate() completes.
                       if(self.text() == 'Hide Details'){
      
                         self.text('Show Details');
      
                       } else {
      
                         self.text('Hide Details');
                       }
                  }); 
              }); 
      
           }   
      });
      

      【讨论】:

      • 这个答案对我帮助很大!!谢谢@renab
      【解决方案3】:

      尝试只绑定一次click 事件到按钮。当然,您可以使用 on 代替 live

      $('.button').live('click', function(){
          var self = $(this); 
          $(this).siblings('.caption').animate({ 
             height: 'toggle'
             }, 200, function() {
               // Callback after animate() completes.
               if(self.text() == 'Hide Details'){
                 self.text('Show Details');
               } else {
                 self.text('Hide Details');
               }
          }); 
      }); 
      $('.infinite-container').waypoint('infinite', {
          onAfterPageLoad: function() { 
              //Carousel options     
              $('.carousel-container').carousel({
                  options: here,
                  ....
              }); 
              //Button Toggles
           }   
      });
      

      【讨论】:

      • +1 只需添加一次点击处理程序即可避免删除现有的点击处理程序
      【解决方案4】:
      $('.button').click(function(){
      

      您向 每个 具有button 类的按钮添加一个事件处理程序。添加第二个按钮后,您将其添加到每个...,这意味着按钮 1 和按钮 2。依此类推。

      试试

      $('.button').last().click(function(){
      

      【讨论】:

      • 这不会导致单击任何一个按钮多次执行单击处理程序。我相信多次执行 $().click();正在添加多个点击处理程序。
      • 我的解决方案只在最后一个按钮上添加了一个点击处理程序。
      • 我的评论指出,将单击处理程序添加到具有“按钮”类的每个按钮不会导致单击其中任何一个来执行单击处理程序的多个实例,这是问题OP 描述。如果他在他的函数中替换了你的代码,它仍然会向一个按钮添加同一个点击处理程序的多个实例,如果它被执行多次。
      • 是的,我写完评论后才明白你的意思:D 没错,当然,如果可能的话,我强烈建议使用container.on("click", ".button")。不过,这是伪代码,如果在事件处理程序中引用了任何局部变量,我们不会拒绝。
      • 确实,如果没有看到完整的源代码,很难确定直接问题,我自己过去也遇到过这个问题,最终使用了回调生成器(返回函数的函数)和unbind() 方法来解决有点复杂的处理程序链更新
      猜你喜欢
      • 1970-01-01
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 2014-05-22
      • 2015-05-13
      • 1970-01-01
      相关资源
      最近更新 更多