【问题标题】:jquery post code based on scroll position fires twice基于滚动位置的jquery post code触发两次
【发布时间】:2012-02-12 14:19:05
【问题描述】:

我有一段 jquery 可以在我的博客上加载新帖子,问题是它运行了两次,这意味着帖子被重复了。我还想找到一种方法,让它在用户距离文档底部还有几个像素(比如 50 像素)时运行。 (图很简单)。

在调整代码之前,我在获得代码的网站上报告了该错误: http://blog.hycus.com/2011/03/15/infinite-scrolling-like-new-twitter-with-php-mysql-jquery

一条评论建议使用 .data() 但我不太确定它会如何工作。此代码是从一个单独的 js 文件运行的,正文中包含指向它的链接。 Firebug 报告了两个帖子请求,最终我的博客帖子显示了两次。

$(document).ready(function(){
    $(window).scroll(function(){
        if($(window).scrollTop() === $(document).height() - $(window).height()){
            $('div#loadmoreajaxloader').show();
            $.post("blog/loadmore", {pid: $(".blogpost:last").attr("id")}, function(html){
                if(html){
                    $("#bloglist").append(html);
                    $('div#loadmoreajaxloader').hide();
                }else{
                    $('div#loadmoreajaxloader').html('<center>No more posts to show.</center>');
                }
            });
        };
    });
});

我无法发布自己问题的答案...我解决了:

这似乎解决了我的问题,如果有人有更好的解决方法,请告诉我。

还尝试了一些方法来使页面加载在到达页面末尾之前发生(我认为 if ($(window).scrollTop()+50 === $(document).height() - $(window).height()) 可能会奏效)但它们不起作用。

var lid = $(".blogpost:last").attr("id");
$(document).ready(function() {
$(this).scrollTop(0);

$(window).scroll(function() {
    if ($(window).scrollTop() === $(document).height() - $(window).height()) {
        if(lid !== $(".blogpost:last").attr("id")){
            $('div#loadmoreajaxloader').show();
            $.post("blog/loadmore", {
                pid: $(".blogpost:last").attr("id")
            }, function(html) {
                if (html) {
                    $("#bloglist").append(html);
                    $('div#loadmoreajaxloader').hide();
                } else {
                    $('div#loadmoreajaxloader').html('<center>No more posts to show.</center>');
                }
            });
            lid = $(".blogpost:last").attr("id");
        }
    };
});

});

【问题讨论】:

  • 当我 made a demo 进行一些调整以使其在 JSFiddle 上运行时,我看不到重复的行。您确定您的服务器脚本输出的博客文章不超过一篇,但看起来 jQuery 触发了两次?
  • 嗨,Jared,Firebug 正在显示两个帖子,它们收到相同的数据。我看不出服务器脚本会重复的任何原因。这个想法是当它到达页面底部时,它会拉出接下来的十个帖子。
  • 这可能是由于第一次迭代没有足够快地移动页面,所以如果我继续滚动它使用相同的最后一个 id 运行,因为新的 id 尚未加载。有没有办法可以记录运行之间的最后一个 id,然后如果它相同则不运行帖子?

标签: jquery post


【解决方案1】:

查看该代码,我并不特别喜欢它的设置方式。该脚本需要对元素进行一些缓存,这样您就不会不断地调用同一个选择器,例如一遍又一遍。

我在onDOMReady 匿名函数回调中使用了一个inproc(正在进行中)变量。这是在顶层设置的,但由于匿名函数提供的闭包,该变量将保持对包含函数可用。在这里,我测试一下是不是true

您会看到我将所有 jQuery 调用移到开头并将它们添加为变量。这称为缓存,有助于防止在同一个脚本中一遍又一遍地发出相同的请求。它效率更高。注意,有$('div#id') 会起作用,但不需要前缀id;只需以id 开头,例如$('#id')。在这之前的任何事情都是不必要的,IMO。

我还设置了200px 预加载距离。 50px 没有你想象的那么高;几乎看不出有什么不同。

超时完全是为了延迟内容的加载,以便您可以测试滚动。打开 Firebug 以查看 console.log() 消息。

此脚本包含大量与测试相关的变量和函数,但您应该能够删除任何“用于测试目的”或其变体的任何内容,并使其正常工作。

// For test purposes.
var i = 0;

$(document).ready(function(){
    var inproc = false,
        id,
        $win = $(window),
        $doc = $(document),
        $bloglist = $("#bloglist"),
        $loadmore = $('#loadmoreajaxloader'),
        // For test purposes.
        dummycontent = $('.dummycontent').html(),
        loadtimeout = false;

    // Note, load is for testing; it goes with the setTimeout().
    var callbackBlogLoaded = function(html){
        var self = this;

        // For testing purposes.
        if (loadtimeout !== false) {
            loadtimeout = false;

            setTimeout(function(html){
                callbackBlogLoaded.call(self, html);
            }, 3000);

            return false;
        }

        inproc = false;

        // For test purposes.
        i++;
        html = dummycontent;
        if (i > 5) html = '';

        if (html) {
            // For test purposes.
            $bloglist.append('<p style="color: red; font-weight: bold;">i is ' + i + ' of 5 total</p>' + html);
            $loadmore.hide();
        } else {
            // <center> is deprecated; use a class on a P or DIV instead.
            $loadmore.html('<p class="center">No more posts to show.</p>');
        }
    };

    // For test purposes.
    $bloglist.append($('.dummycontent').html());

    $win.scroll(function(){
        // You need to subtract the scroll-load pad distance from the
        // right-side height calculation, not .scrollTop().
        if ($win.scrollTop() > ($doc.height() - $win.height() - 200)){
            if (inproc == true) {
                // For testing purposes.
                console.log('Content load blocked: In process with another request.');

                return false;
            }

            inproc = true;
            id = $bloglist.has(':last').attr('id');

            // For test purposes
            id = 10;
            loadtimeout = true;

            $loadmore.show();

            // The /echo/html/ is for testing purposes.
            $.post("/echo/html/", { pid: id }, callbackBlogLoaded);
        };
    });
});

http://jsfiddle.net/xUsEA/2/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多