jQuery does not work in Ajax generated content

I have had this problem for some time and it’s really bugging me.

I’m using two wordpress plugin, one for ajax load more and the other for ajax read more. you can see them in the links below:

Read More

they both are working fine, but “Read More” does not work in the posts generated by “Load More”. here’s the jQuery code in “Read More” which i think should be edited:

var backgroundAction = false;

jQuery.fn.AJAXReadMore = function (options) {
    var $ = jQuery,
        options = $.extend({
            animateSpeed: 'slow',
            errorMessage: "Error.<br/>Try again later.",
            errorClass: "loading-error",
            loadingClass: "loading",
            spacerClass: "loading-spacer",
            loadedClass: "loaded",
            contentElSelector: ".entry-part",
            moreElSelector: ".more-link",
            moreContainerSelector: ".more-link-container",
            onUpdateEvent: "onupdate",
            parentScrollableEl: $("html,body"),
            scroll: true,
            scrollToSelector: ".entry-header",
            scrollLowBound: 0,
            ajaxData: {}
        }, options);

    return this.each(function () {
        var post = {
            data: $.extend(options.ajaxData, {
                'AJAX-mode': '1'
            }),
            moreLink: $(options.moreElSelector, this),
            navigation: $(options.moreContainerSelector, this)
                .add(options.moreElSelector, this),
            content: $(options.contentElSelector, this),
            el: $(this)
        },
        busy = false;
        if (!(post.content.length)) post.content = post.el;

        $(post.moreLink).on('click', function () {

            if (busy) return false;
            var scroll = (options.scroll) && !(backgroundAction);
            busy = true;

            post.scrollTo = $(options.scrollToSelector, post.el);
            if (!(post.scrollTo.length)) post.scrollTo = post.el;

            var newContent = post.content.clone(true)
                .hide()
                .addClass(options.loadingClass)
                .html("")
                .insertAfter(post.content),
                spacerHeight1 = options.parentScrollableEl.scrollTop() + options.parentScrollableEl.height() - newContent.offset().top,
                spacerHeight = (spacerHeight1 > 0) ? spacerHeight1 : 0,
                spacer = newContent.clone()
                    .addClass(options.spacerClass)
                    .addClass(options.loadingClass)
                    .insertBefore(newContent)
                    .animate({
                    height: "0px"
                },
                options.animateSpeed)
                    .show();
            post.navigation.addClass(options.loadingClass);
            if (scroll) {
                if ((post.scrollTo.offset().top - options.parentScrollableEl.scrollTop() > options.scrollLowBound)) {
                    options.parentScrollableEl.animate({
                        scrollTop: post.scrollTo.offset().top + "px"
                    }, options.animateSpeed);
                };
            };
            $.when(
            $.ajax({
                type: "GET",
                url: post.moreLink.attr('href'),
                dataType: "html",
                cache: true,
                data: post.data
            }),
            post.scrollTo,
            options.parentScrollableEl).then(
            /*success:*/
            function (args) {
                /*args: [ data, "success", jqXHR ]*/
                var data = args[0];
                var dataObj;
                var bodyEl = {
                    length: 0
                };
                try {
                    dataObj = $(data);
                    bodyEl = dataObj.find('body');
                } catch (e) {};
                var dt = {
                    url: post.moreLink.attr('href'),
                    referrer: $(location).attr('href')
                };
                var textStatus = args[1];

                if (bodyEl.length) {
                    dt = $.extend(dt, {
                        body: bodyEl.html(),
                        title: dataObj.find('title').text()
                    });
                } else {
                    dt = $.extend(dt, {
                        body: data
                    });
                };

                post.navigation.addClass(options.loadedClass)
                    .removeClass(options.loadingClass);
                newContent.html(dt.body)
                    .show()
                    .removeClass(options.loadingClass)
                    .slideDown(options.animateSpeed)
                    .trigger(options.onUpdateEvent)
                    .trigger('counter.hit', dt);
                spacer.addClass(options.loadedClass)
                    .removeClass(options.loadingClass)
                    .slideUp(options.animateSpeed, function () {
                    $(this).remove();
                });
                busy = false;
            },
            /*error:*/
            function () {
                /*args: [ request, "error", jqXHR ]*/
                var request = args[0],
                    textStatus = args[1];
                newContent.remove();
                post.navigation.addClass(options.errorClass);
                spacer.hide()
                    .addClass(options.errorClass)
                    .removeClass(options.loadingClass)
                    .html(options.errorMessage)
                    .fadeIn(options.animateSpeed)
                    .delay(1000)
                    .fadeOut(options.animateSpeed)
                    .delay(100)
                    .hide(options.animateSpeed, function () {
                    $(this).remove();
                    post.navigation.removeClass(options.loadingClass)
                        .removeClass(options.errorClass);
                });
                busy = false;
            });
            return false;
        });

    });
};

P.S: I have used .live, .on and .delegate and they did non work.

Edit: and This is the “Load More” code. any idea how to trigger the “Read More” through this?


jQuery(document).ready(function() {

// The number of the next page to load (/page/x/).
var pageNum = parseInt(pbd_alp.startPage) + 1;

// The maximum number of pages the current query can return.
var max = parseInt(pbd_alp.maxPages);

// The link of the next page of posts.
var nextLink = pbd_alp.nextLink;

/**
 * Replace the traditional navigation with our own,
 * but only if there is at least one page of new posts to load.
 */
if(pageNum <= max) {
    // Insert the "More Posts" link.
    $('#ajaxload')
        .append('<div class="pbd-alp-placeholder-'+ pageNum +'"></div>')
        .append('<p id="pbd-alp-load-posts"><a href="#">Show More</a></p>');

    // Remove the traditional navigation.
    $('.pagination').remove();
}


/**
 * Load new posts when the link is clicked.
 */
$('#pbd-alp-load-posts a').click(function() {

    // Are there more posts to load?
    if(pageNum <= max) {

        // Show that we're working.
        $(this).text('');
        $(this).append('<img src="http://bluhbluh.com/wp-content/themes/coffebook/img/loader.gif">');

        $('.pbd-alp-placeholder-'+ pageNum).load(nextLink + ' .post',
            function() {
                // Update page number and nextLink.
                pageNum++;
                nextLink = nextLink.replace(//page/d{0,9}/, '/page/'+ pageNum);

                // Add a new placeholder, for when user clicks again.
                $('#pbd-alp-load-posts')
                    .before('<div class="pbd-alp-placeholder-'+ pageNum +'"></div>')

                // Update the button message.
                if(pageNum <= max) {
                    $('#pbd-alp-load-posts a').text('Show More');
                } else {
                    $('#pbd-alp-load-posts a').text('No More Posts');
                }
            }
        );
    } else {
        $('#pbd-alp-load-posts a').append('.');
    }   

    return false;
});

});

Related posts

Leave a Reply

4 comments

  1. Use .on() jQuery method.

    $(post.moreLink).on('click',function(){ /**codehere**/ });
    

    .on() allow to add events on dynamically loaded content.

  2. For actions on future elements, you should use jQuery on.

    $(document).on('click',post.moreLink, function(){ 
    // write your codes
    });
    

    Note that it is different from $(post.moreLink).on('click',function(){.....}); which will not affect future elements. Also, make sure that your variable post.moreLink is set.

  3. I dont have the right to comment, so I use an answer and I hope It helps.

    I think the problem is related to triggering the Jquery action of first plugin after the DOM is updated by second plugin. In other words, you need to call the actions of Readmore plugin in the AJAX function relatif to LoadMore Plugin (after results of LoadMore are returned).

    I think I have already faced such issue here:

    jquery script of wordpress plugin dont work in content loaded via ajax

  4. You can fix this two ways.

    Yes one is to use .live method, which if used correctly certainly works.

    2nd way is to create method for binding events and use this method in ajax callbacks which run after the content has been received and added to document.

    In your code i can see you are doing stuff on successful data load but nothing indicates that you are actually binding any events to new content