【问题标题】:jQuery does not work in Ajax generated contentjQuery 在 Ajax 生成的内容中不起作用
【发布时间】:2013-03-09 07:15:57
【问题描述】:

这个问题我已经有一段时间了,真的很困扰我。

我正在使用两个 wordpress 插件,一个用于 ajax 加载更多,另一个用于 ajax 阅读更多。你可以在下面的链接中看到它们:

它们都工作正常,但“阅读更多”在“加载更多”生成的帖子中不起作用。这是我认为应该编辑的“阅读更多”中的 jQuery 代码:

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:我用过.live.on.delegate,但它们没有用。

编辑:这是“加载更多”代码。知道如何通过这个触发“阅读更多”吗?

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

});

【问题讨论】:

  • 如果您将 AJAXReadMore( ... your options ... ) 调用到新添加的内容,将不起作用?例如通过将代码添加到 LoadMore 插件中的load 回调? (或者通过触发自定义事件,让代码更清晰)
  • 感谢您的回答。我该怎么做呢?

标签: jquery ajax wordpress load


【解决方案1】:

使用.on()jQuery 方法。

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

.on() 允许在动态加载的内容上添加事件。

【讨论】:

  • .on('click',function(){...}).click(function(){...}).bind('click',function(){...}) 是相同的。我认为您指的是委托$(commonParent).on('click','.selector',function(){...}),但您的示例未使用委托。
  • 谢谢,但正如我所说,我已经尝试过并生活过。您的代码也不起作用。
【解决方案2】:

对于未来元素的操作,您应该使用 jQuery on

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

请注意,它与$(post.moreLink).on('click',function(){.....}); 不同,后者不会影响未来的元素。另外,请确保您的变量 post.moreLink 已设置。

【讨论】:

  • 我确实用你的代码替换了我的代码,但它的作用是当点击一个项目时,页面中的所有项目一个接一个地加载,然后再次点击 Ajax 生成的项目,以前的项目再次加载......真的很奇怪。
  • 您应该确保post.more 指的是一个独特的项目。如果while页面再次加载,你应该让function()变成function(e),然后在你的函数的第一行添加e.preventDefault()
【解决方案3】:

我没有评论的权利,所以我使用一个答案,我希望它有所帮助。

我认为问题与在第二个插件更新 DOM 后触发第一个插件的 Jquery 操作有关。也就是说,需要调用LoadMore Plugin的AJAX函数relatif中Readmore插件的动作(LoadMore返回结果后)。

我想我已经在这里遇到过这样的问题:

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

【讨论】:

  • 这正是问题所在。我如何触发它?做了我能做的,但没有用。如果你能下载这两个插件并看看它是如何的,我将不胜感激。
  • 我保证会这样做,但不是现在,因为我有点忙。同时,我只是请您仔细阅读 ReadMore 的 JS 文件,并在其中找到负责 ReadMore 事件的函数。然后在 LoadMore 的 ajax 成功处理程序中调用这个函数。这就是您可以在由 AJAX 更新的 DOM 上触发 Jquery 操作的方式。祝你好运
【解决方案4】:

您可以通过两种方式解决此问题。

是的,一种是使用 .live 方法,如果使用得当,肯定有效。

第二种方法是创建绑定事件的方法,并在 ajax 回调中使用此方法,该回调在接收到内容并添加到文档后运行。

在您的代码中,我可以看到您正在成功加载数据,但没有任何迹象表明您实际上将任何事件绑定到新内容

【讨论】:

  • .live() 方法有点过时,被.on()取代
  • 您是在将元素添加到 DOM 之前还是之后运行链接绑定代码?
  • 我真的不知道。正如我所说,这是一个插件。你可以在上面给出的链接下载它。我编辑了我的问题并粘贴了整个 jQuery 代码。
猜你喜欢
  • 2014-09-26
  • 2014-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
  • 2014-06-09
  • 1970-01-01
相关资源
最近更新 更多