jQuery funktioniert nicht in Ajax-generierten Inhalten

Lesezeit: 7 Minuten

Benutzer-Avatar
Mehdi Amiri

Ich habe dieses Problem seit einiger Zeit und es nervt mich wirklich.

Ich verwende zwei WordPress-Plugins, eines für Ajax Load More und das andere für Ajax Read More. Sie können sie in den folgenden Links sehen:

Beide funktionieren einwandfrei, aber “Read More” funktioniert nicht in den von “Load More” generierten Beiträgen. Hier ist der jQuery-Code in “Weiterlesen”, der meiner Meinung nach bearbeitet werden sollte:

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;
        });

    });
};

PS: Ich habe verwendet .live, .on und .delegate und sie haben nicht gearbeitet.

Bearbeiten: und Dies ist der Code “Mehr laden”. Irgendeine Idee, wie man das “Weiterlesen” dadurch auslöst?


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;
});

});

  • Würde es nicht funktionieren, wenn Sie AJAXReadMore( … your options … ) für den neu hinzugefügten Inhalt aufrufen? zB durch Hinzufügen Ihres Codes zur load Callback im LoadMore-Plugin ? (oder indem Sie dort ein benutzerdefiniertes Ereignis auslösen, um den Code etwas übersichtlicher zu halten)

    – t.niese

    9. März 2013 um 10:00 Uhr

  • Danke für deine Antwort. wie kann ich das genau machen?

    – Mehdi Amiri

    9. März 2013 um 18:25 Uhr

Benutzer-Avatar
Dipesch Parmar

Verwenden .on() jQuery-Methode.

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

.on() ermöglichen das Hinzufügen von Ereignissen zu dynamisch geladenen Inhalten.

  • .on('click',function(){...}), .click(function(){...}) und .bind('click',function(){...}) sind gleich. Ich denke, Sie meinen den Delegierten $(commonParent).on('click','.selector',function(){...}) aber Ihr Beispiel verwendet keinen Delegaten.

    – t.niese

    9. März 2013 um 9:10 Uhr


  • danke aber wie gesagt, ich habe schon mal anprobiert und gelebt. dein Code funktioniert auch nicht.

    – Mehdi Amiri

    9. März 2013 um 9:16 Uhr

Für Aktionen auf zukünftigen Elementen sollten Sie jQuery verwenden on.

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

Beachten Sie, dass es sich von unterscheidet $(post.moreLink).on('click',function(){.....}); die zukünftige Elemente nicht beeinflussen. Stellen Sie außerdem sicher, dass Ihre Variable post.moreLink eingestellt ist.

  • Ich habe meinen Code durch Ihren ersetzt, aber wenn Sie auf ein Element klicken, werden alle Elemente auf der Seite nacheinander geladen, und wenn Sie dann erneut auf die von Ajax generierten Elemente klicken, werden die vorherigen Elemente erneut geladen … . sehr seltsam.

    – Mehdi Amiri

    9. März 2013 um 9:46 Uhr


  • Das sollten Sie sicherstellen post.more bezieht sich auf ein Unikat. Wenn die While-Seite erneut geladen wird, sollten Sie dies vornehmen function() werden function(e) und dann hinzufügen e.preventDefault() in der ersten Zeile Ihrer Funktion

    – RRikesh

    9. März 2013 um 9:53 Uhr

Benutzer-Avatar
Adib Aroui

Ich habe kein Recht zu kommentieren, also verwende ich eine Antwort und hoffe, dass es hilft.

Ich denke, das Problem hängt mit dem Auslösen der Jquery-Aktion des ersten Plugins zusammen, nachdem das DOM durch das zweite Plugin aktualisiert wurde. Mit anderen Worten, Sie müssen die Aktionen des Readmore-Plugins in der AJAX-Funktion in Bezug auf das LoadMore-Plugin aufrufen (nachdem die Ergebnisse von LoadMore zurückgegeben wurden).

Ich glaube, ich hatte hier schon einmal ein solches Problem:

Das jquery-Skript des WordPress-Plugins funktioniert nicht in Inhalten, die über Ajax geladen werden

  • Genau das ist das Problem. wie löse ich das aus? habe getan, was ich konnte, aber es hat nicht funktioniert. Ich wäre dankbar, wenn Sie beide Plugins herunterladen und sehen könnten, wie es ist.

    – Mehdi Amiri

    10. März 2013 um 10:26 Uhr

  • Ich verspreche, es zu tun, aber nicht jetzt, weil ich ein bisschen beschäftigt bin. In der Zwischenzeit bitte ich Sie nur, die JS-Dateien von ReadMore sorgfältig zu lesen und die Funktion darin zu finden, die für das ReadMore-Ereignis verantwortlich ist. Rufen Sie dann diese Funktion im Ajax-Erfolgshandler von LoadMore auf. So können Sie eine Jquery-Aktion auf einem von AJAX aktualisierten DOM auslösen. Viel Glück

    – Adib Aroui

    10. März 2013 um 11:31 Uhr

Sie können dies auf zwei Arten beheben.

Ja, man muss die .live-Methode verwenden, die bei richtiger Anwendung sicherlich funktioniert.

Der zweite Weg besteht darin, eine Methode zum Binden von Ereignissen zu erstellen und diese Methode in Ajax-Callbacks zu verwenden, die ausgeführt werden, nachdem der Inhalt empfangen und dem Dokument hinzugefügt wurde.

In Ihrem Code kann ich sehen, dass Sie beim erfolgreichen Laden von Daten Dinge tun, aber nichts weist darauf hin, dass Sie tatsächlich Ereignisse an neue Inhalte binden

1251710cookie-checkjQuery funktioniert nicht in Ajax-generierten Inhalten

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy