我有一段 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");
}
};
});
});
最佳答案
看着那个代码,我不是特别喜欢它的设置方式。例如,脚本需要对元素进行一些缓存,这样您就不会不断地反复调用同一个选择器。
我在 inproc
匿名函数回调中使用了 onDOMReady
(in process) 变量。这是在顶层设置的,但由于匿名函数提供的闭包,该变量将保持可用于包含函数。在这里,我测试一下它是否是 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/
关于基于滚动位置的 jquery 邮政编码触发两次,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9249471/