EHerman
EHerman

Reputation: 1892

Re-Execute Javascript after Ajax Success

I have a list of posts on a page that when hovered over reveal a overlay that says 'read more'. At the bottom of the page is an button that runs an ajax function to get more posts. After the ajax has successfully loaded the 'read more' thumbnail overlay no longer reveals on mouse over.

This has to be because the javascript has executed already, and I've loaded more elements into the dom. How can I re-execute the same JS function to allow for the new posts to have the overlay as well?

I've tried re-running my function on ajax success, but it didn't seem to do anything. No error or anything.

JavaScript

jQuery(".thumboverlay").mouseenter(function() {
                    jQuery(this).stop().animate({
                        opacity: 1
                    });
                });

                    jQuery(".inspiration-project-title").mouseenter(function() {
                        jQuery(this).parent(".brick").find(".thumboverlay").stop().animate({
                            opacity: 1
                        });
                    });

                jQuery(".thumboverlay").mouseleave(function() {
                    jQuery(this).stop().animate({
                        opacity: 0
                    });
                });
                    jQuery(".inspiration-project-title").mouseleave(function() {
                        jQuery(this).parent(".brick").find(".thumboverlay").stop().animate({
                            opacity: 0
                        });
                    });

HTML/PHP

<a href='.get_permalink().'>
   <div class="inspirations-page-featured-image">
     <div class="thumboverlay">
       <p>READ MORE</p>
      </div>'.$printFeaturedImage.'
    </div>
</a>

Ajax

// ajaxLoop.js  
jQuery(function($){  
    var page = 1;  
    var loading = true;  
    var $window = $(window);  
    var $ajaxLoadMoreButton = $("body.blog .ajaxLoadMoreButton");  
    var $content = $("body.blog #container");  
    var load_posts = function(){  
            $.ajax({  
                type       : "GET",  
                data       : {numPosts : 1, pageNumber: page},  
                dataType   : "html",  
                url        : "wp-content/themes/twentytwelve/loopHandler.php", 
                beforeSend : function() {  
                    if(page !=0) {  
                         $ajaxLoadMoreButton.before('<div id="temp_load" style="text-align:center"><img src="wp-content/themes/twentytwelve/images/ajax-loader.gif" /></div>');                          
                    }  
                },  
                success    : function(data){  
                    $data = $(data);  
                    if($data.length){  
                        $data.hide();  
                        $content.isotope('insert', $(data) );
                        $data.fadeIn(500, function(){  
                            $("#temp_load").remove();  
                            loading = false;  
                        });
                    } else {  
                        $("#temp_load").remove();  
                        $ajaxLoadMoreButton.fadeOut().before('<p class="no-more-posts-warning">Sorry, there are currently no more posts to load.</p>');
                    }  
                },  
                error     : function(jqXHR, textStatus, errorThrown) {  
                    $("#temp_load").remove();  
                    alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);  
                }  
        });  
    }  

    $ajaxLoadMoreButton.click(function() {                  
                loading = true;  
                page++;  
                load_posts();   
    });  

});  

Upvotes: 1

Views: 1604

Answers (3)

eggward
eggward

Reputation: 345

As jfriend00 suggested, you can use delegated event handling. In Jquery you can do it like.

$( "body" ).delegate( ".ajaxLoadMoreButton", "click", function() {
                  loading = true;  
                page++;  
                load_posts();   
});

This will bind the function to all elements matching the selector now and the future (when n new elements are added in the page) Read more here about delegate

Upvotes: 1

EHerman
EHerman

Reputation: 1892

I was eventually able to re-fire the function after shifting some things around and adding that section of the overall function to its own individual function.

function re_fire_hoverStates() {
   jQuery(".thumboverlay").mouseenter(function() {
                    jQuery(this).stop().animate({
                        opacity: 1
                    });
                });

                    jQuery(".inspiration-project-title").mouseenter(function() {
                        jQuery(this).parent(".brick").find(".thumboverlay").stop().animate({
                            opacity: 1
                        });
                    });

                jQuery(".thumboverlay").mouseleave(function() {
                    jQuery(this).stop().animate({
                        opacity: 0
                    });
                });
                    jQuery(".inspiration-project-title").mouseleave(function() {
                        jQuery(this).parent(".brick").find(".thumboverlay").stop().animate({
                            opacity: 0
                        });
                    });
}

Then I did ran the function for the first time on page load, $(document).ready(re_fire_hoverStates);

and then ran the function again, as you had suggested, on Ajax success:

// ajaxLoop.js  
jQuery(function($){  
    var page = 1;  
    var loading = true;  
    var $window = $(window);  
    var $ajaxLoadMoreButton = $("body.blog .ajaxLoadMoreButton");  
    var $content = $("body.blog #container");  
    var load_posts = function(){  
            $.ajax({  
                type       : "GET",  
                data       : {numPosts : 1, pageNumber: page},  
                dataType   : "html",  
                url        : "wp-content/themes/twentytwelve/loopHandler.php", 
                beforeSend : function() {  
                    if(page !=0) {  
                         $ajaxLoadMoreButton.before('<div id="temp_load" style="text-align:center"><img src="wp-content/themes/twentytwelve/images/ajax-loader.gif" /></div>');                          
                    }  
                },  
                success    : function(data){  
                    $data = $(data);  
                    if($data.length){  
                        $data.hide();  
                        $content.isotope('insert', $(data) );
                        $data.fadeIn(500, function(){  
                            $("#temp_load").remove();  
                            loading = false;
                            re_fire_hoverStates();  
                        });
                    } else {  
                        $("#temp_load").remove();  
                        $ajaxLoadMoreButton.fadeOut().before('<p class="no-more-posts-warning">Sorry, there are currently no more posts to load.</p>');
                    }  
                },  
                error     : function(jqXHR, textStatus, errorThrown) {  
                    $("#temp_load").remove();  
                    alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);  
                }  
        });  
    }  
    $ajaxLoadMoreButton.click(function() {                  
                loading = true;  
                page++;  
                load_posts();   
    });  
});

Upvotes: 0

jfriend00
jfriend00

Reputation: 707298

There are a couple possible solutions here:

  1. Create a new function that will find just the newly added elements and hook up the appropriate event handlers for them and call that function in the success handler of the ajax function after the new elements have been loaded.

  2. Use delegated event handling that will work on newly added elements automatically.

  3. Change how you're adding new elements. Don't do things like elem.innerHTML += htmlstring because that recreates all existing elements ruining their event handlers.

Which one is better or exactly how to implement any of them depends upon your HTML and what you're doing with your javascript so we can't really advise more specifically without seeing your exact situation (relevant HTML and JS).

Upvotes: 1

Related Questions