我要做的是将新的“.post”(已被无限滚动脚本检索)推入到包含所有“.post”的数组中。
完整代码:https://gist.github.com/sxxfi/8296403
现场演示:http://soof-show.tumblr.com(使用键盘箭头键导航帖子)
最初,五个“.post”显示在“.content”div中,然后每次点击“更多”按钮时,它会再添加5个“.post”到“.content”。
问题是数组长度不计入新的“.post”,因此它会保持循环前5个。
如果你能帮忙解决这个问题,请提前感谢。
使用Javascript:
$(document).ready(function(){
// I N F I N I T E S C R O L L
$('.content').infinitescroll({
navSelector : ".navigation",
nextSelector : ".navigation .next_page",
itemSelector : ".content .post",
behavior: "twitter"
});
$(window).unbind('.infscr');
$('.next_page').click(function(){
$(document).trigger('retrieve.infscr');
return false;
});
$(document).ajaxError(function(e,xhr,opt){
if (xhr.status == 404) $('.next_page').remove();
});
// I M A G E S L I D E R
var obj = $(".post");
var arr = $.makeArray(obj);
var lastDiv = $(".post");
var indexNum = arr.length-1;
$(window).keydown(function (e) {
if (e.keyCode == 37) { // L E F T
lastDiv.fadeOut(800);
indexNum--;
if (indexNum == -1) indexNum = arr.length-1; //if goes beyond first post, goto the last post
$(arr[indexNum]).appendTo(".postslide").fadeIn(800);
// C E N T E R
var width = $(arr[indexNum]).width();
var marginLeft = width / 2;
$(arr[indexNum]).css('margin-left', -marginLeft);
}
if (e.keyCode == 39) { // R I G H T
$('#instruction').fadeOut();
lastDiv.fadeOut(800);
indexNum++;
if (indexNum == arr.length) indexNum = 0; //if goes beyond last post, goto the first post
$(arr[indexNum]).appendTo(".postslide").fadeIn(800);
// C E N T E R
var width = $(arr[indexNum]).width();
var marginLeft = width / 2;
$(arr[indexNum]).css('margin-left', -marginLeft);
}
});
});
更新
$(document).ready(function(){
// I N F I N I T E S C R O L L
$('.content').infinitescroll({
navSelector : ".navigation",
// selector for the paged navigation (it will be hidden)
nextSelector : ".navigation .next_page",
// selector for the NEXT link (to page 2)
itemSelector : ".content .post",
// selector for all items you'll retrieve
behavior: "twitter"
});
// kill scroll binding
$(window).unbind('.infscr');
// manual click
$('.next_page').click(function(){
$(document).trigger('retrieve.infscr');
return false;
});
// remove the paginator done
$(document).ajaxError(function(e,xhr,opt){
if (xhr.status == 404) $('.next_page').remove();
});
// I M A G E S L I D E R
var obj = $(".post");
var indexNum = obj.length-1;
var lastDiv = $(".post");
$(window).keydown(function (e) {
if (e.keyCode == 37) { // L E F T
lastDiv.fadeOut(800);
indexNum--;
if (indexNum == -1) indexNum = obj.length-1; //if goes beyond first post, goto the last post
$(obj[indexNum]).appendTo(".postslide").fadeIn(800);
// C E N T E R
var width = $(obj[indexNum]).width();
var marginLeft = width / 2;
$(obj[indexNum]).css('margin-left', -marginLeft);
}
if (e.keyCode == 39) { // R I G H T
$('#instruction').fadeOut();
lastDiv.fadeOut(800);
indexNum++;
if (indexNum == obj.length) indexNum = 0; //if goes beyond last post, goto the first post
$(obj[indexNum]).appendTo(".postslide").fadeIn(800);
// C E N T E R
var width = $(obj[indexNum]).width();
var marginLeft = width / 2;
$(obj[indexNum]).css('margin-left', -marginLeft);
}
});
});
答案 0 :(得分:3)
jQuery选择器在调用jQuery函数时查询DOM,因此它们在给定时刻选择与选择器匹配的元素。
即使应该与您的选择器匹配的新元素稍后添加到DOM中,它们也不会被选中,因为没有通知jQuery重新评估选择器,即使有什么事情,jQuery也没有内部状态保存所有创建的jQuery对象。这意味着选择器为not live。
这里的主要问题是你永远不会更新所选DOM元素的数组,所以即使将新元素添加到DOM,你仍然会遍历原始数组。
更新jQuery对象很简单,您只需在代码中随时调用obj = $(".post")
,obj
变量就会更新。我们只需要知道何时调用它。
由于您使用Infinite Scroll加载新元素,我们需要查看它documentation,或者由于文档中当前有大洞,因此最好查看{{3 }}
查看infinitescroll
函数:
$.fn.infinitescroll = function infscr_init(options, callback) {
...
第二个参数称为callback
,在检查源代码以及传递和调用此参数的方式后,您可以看到在检索到新元素后将调用它。我们试试这个参数:
$('.content').infinitescroll({
navSelector : ".navigation",
// selector for the paged navigation (it will be hidden)
nextSelector : ".navigation .next_page",
// selector for the NEXT link (to page 2)
itemSelector : ".content .post",
// selector for all items you'll retrieve
behavior: "twitter"
}, function () {
obj = $(".post");
console.log("Current length is: " + obj.length); //this line is not necessary, just here for debug purposes.
});
假设变量obj
已经存在,这将更新它的值。
请注意,在此答案的先前版本中,我调用了此回调函数recountPosts()
。后来我决定它只是一个内联匿名函数,因为它只能从一个地方调用。
你差不多完成了,但是...你有其他变量取决于这个选择器。即arr
和lastDiv
。检查您的源代码后,似乎没有必要:
arr
是一个由jQuery对象选择的元素组成的数组,虽然source code,它有一个基于零的数字索引器和一个长度属性就像一个数组,因此您可以在代码中的任意位置替换arr
obj
。
lastDiv
有一个误导性的名字。它与obj
具有相同的元素,而不仅仅是最后一个元素。因此,它也可以用obj
替代。
因此,声明变量的部分可以缩小为:
// I M A G E S L I D E R
var obj = $(".post");
var indexNum = obj.length-1;
我还查看了你的keydown
事件处理程序。其中有很多重复的代码。这很容易在以后引入错误(事实上你已经有了一个错误:如果你在开始时按向左而不是向右,键盘的初始图片不会消失)。
让我稍微为你重组一下:
$(window).keydown(function (e) {
if (e.keyCode === 37) { // L E F T
indexNum--;
}
if (e.keyCode === 39) { // R I G H T
indexNum++;
}
if (e.keyCode === 37 || e.keyCode === 39) {
$('#instruction').fadeOut();
obj.fadeOut(800);
if (indexNum === -1) {
indexNum = obj.length-1; //if goes beyond first post, goto the last post
}
if (indexNum === obj.length) {
indexNum = 0; //if goes beyond last post, goto the first post
}
$(obj[indexNum]).appendTo(".postslide").fadeIn(800);
var width = $(arr[indexNum]).width();
var marginLeft = width / 2;
$(obj[indexNum]).css('margin-left', -marginLeft);
}
});
它完成了!
不,当然没有完成。它还远没有完成,还有许多很多需要改进的东西。
就像删除每个按键上的margin-left
的丑陋重新计算一样,用几行css解决它。作为一个拇指规则:如果某些东西可以用css而不是javascript来解决它应该是。
或者在infinitescroll(...)
而不是$(".postslide")
上调用$(".content")
并从.appendTo(".postslide")
之前删除完全不必要的fadeIn()
,因为元素已经附加,重新使用它们是浪费资源。
或移动常数,例如800 ms的淡入淡出长度到代码的开头,给它们一个像var fadeLength = 800;
这样的变量并使用它。
而且我很确定还有很多其他事情可以做得更好,但这就是编程方式:)
因此,如果您位于幻灯片的末尾,您还希望仅显示更多按钮。你写了这个:
if (indexNum === 14){
$('.next_page').html('<img src="http://long_url/">');
}
为什么要将14硬编码到源代码中?为什么你甚至关心加载了多少张图片以及加载多少张图片?代码的给定部分只需知道您是否在最后。如果您有一个关于加载幻灯片数量的变量,您可以轻松检查您是否在最后一个索引。您做拥有该变量obj.length
:
if (indexNum === obj.length-1){
$('.next_page').html('<img src="http://long_url/">');
}
这样,如果是第30个,第45个或第900个,那么最后一张幻灯片上会出现更多按钮而不关心。
加载新内容后,您还需要此按钮消失。这进入了infinitescroll的回调:
function () {
obj = $(".post");
console.log("Current length is: " + obj.length); //this line is not necessary, just here for debug purposes.
$('.next_page').html('');
}
您可以做的另一件事是,不是显示更多按钮,而是可以从代码中触发更多事件。这样,当用户到达最后一张幻灯片时,新幻灯片会自动加载。
此外,只有在实际需要加载幻灯片时才需要这样做。您可以检查当前状态的isDone
属性,该属性告诉您“无限滚动是否完成”,因此不再需要加载元素。
$('.content').data('infinitescroll').options.state.isDone === false
因此,不是显示更多按钮的部分,而是可以写下:
if (indexNum === obj.length-1 && !$('.content').data('infinitescroll').options.state.isDone){
$(document).trigger('retrieve.infscr');
}
答案 1 :(得分:0)
<强>问题:强>
您在页面加载时设置值,而在滚动发生时或在其他键绑定时不更新
<强>解决方案:强>
// I M A G E S L I D E R
var obj = $(".post");
var arr = $.makeArray(obj);
var lastDiv = $(".post:last");
var indexNum = arr.length-1;
$(window).keydown(function (e) {
obj = $(".post");
arr = $.makeArray(obj);
lastDiv = $(".post:last");
indexNum = arr.length-1;
//other code
});