admin管理员组

文章数量:1410737

I have a page loading content with the waypoints infinite scroller plugin.

On the success of the AJAX call and after DOM elements are added, a callback runs to re-initilize javascript functionality, like carousels, buttons and other animation.

On the first AJAX call, buttons tasked with toggling work properly. On the next AJAX call, the new DOM items work, but the previous buttons now execute toggles twice when clicked. On the third call, original items now run three times, the second items twice and the new ones once, so on and so fourth, continuing to pound as AJAX content is called.

How can I isolate the callback to not affect the previously loaded content, or, is there a way to set a global state for the JS, so that I don't need the callback each time?

Some pseudo code:

$('.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() pletes.
                 if(self.text() == 'Hide Details'){

                   self.text('Show Details');

                 } else {

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

     }   
});    

Edit: Thanks everybody. All the answers lead me to differing but appropriate solutions. The selected was picked as it's a great collection of all the suggested issues and worth the read.

I have a page loading content with the waypoints infinite scroller plugin.

On the success of the AJAX call and after DOM elements are added, a callback runs to re-initilize javascript functionality, like carousels, buttons and other animation.

On the first AJAX call, buttons tasked with toggling work properly. On the next AJAX call, the new DOM items work, but the previous buttons now execute toggles twice when clicked. On the third call, original items now run three times, the second items twice and the new ones once, so on and so fourth, continuing to pound as AJAX content is called.

How can I isolate the callback to not affect the previously loaded content, or, is there a way to set a global state for the JS, so that I don't need the callback each time?

Some pseudo code:

$('.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() pletes.
                 if(self.text() == 'Hide Details'){

                   self.text('Show Details');

                 } else {

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

     }   
});    

Edit: Thanks everybody. All the answers lead me to differing but appropriate solutions. The selected was picked as it's a great collection of all the suggested issues and worth the read.

Share edited Apr 29, 2013 at 21:05 PHPeer asked Apr 29, 2013 at 18:14 PHPeerPHPeer 6591 gold badge7 silver badges20 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 2

Check out this answer. I think it is the same situation you are having and has a solution:

Best way to remove an event handler in jQuery?

You are attaching a new click handler each time that block of code gets executed. The result is multiple click handlers being bound to your button. Use jQuery's unbind: http://api.jquery./unbind/ to remove any click handler(s) before adding a new one:

$('.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() pletes.
                 if(self.text() == 'Hide Details'){

                   self.text('Show Details');

                 } else {

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

     }   
});

Try bind only once click event to button. Of course you can use on instead of live.

$('.button').live('click', function(){
    var self = $(this); 
    $(this).siblings('.caption').animate({ 
       height: 'toggle'
       }, 200, function() {
         // Callback after animate() pletes.
         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
     }   
});
$('.button').click(function(){

You add an event handler to every button that has the class button. When the second button is added then you add it to every ... which means button 1 and button 2. And so on.

Try

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

本文标签: javascriptCallbacks running twice after AJAX content loadedStack Overflow