我有一个显示块的页面。它们是4个列和4行,共16个块 但是,当你到达页面底部时,a有一个AJAX函数,每次到达页面底部时都会加载16个块。
我想为这些块加载动画(我将不透明度从0更改为1),为此,我使用此代码逐渐向这些元素添加一个类:
第1栏:
(.colnum1
对应于第1列中的块)
$('.colnum1').each(function(u){
setTimeout(function(){
$('.colnum1').eq(u).addClass('selected');
}, 1200 * u);
});
第2栏:
(.colnum2
对应于第2列中的块)
$('.colnum2').each(function(z){
setTimeout(function(){
$('.colnum2').eq(z).addClass('selected');
}, 300 + 1200 * z);
});
这一切对前16个元素都有效。
但是,当我加载接下来的16个元素时,它们会出现延迟(在动画onload
出现之前)。
我已经弄清楚这个延迟对应于什么...
当我到达页面底部并再次执行jQuery .each()
函数时,它们会在新元素之前抛出已存在的元素......这是有道理但不是不需要。
我试图重写这些功能,以便它不会抛弃已经加载的功能。元素第一。
使用以下代码:(.selected
是添加onload
动画的类)
$('.colnum1:not(.selected)').each(function(u){
setTimeout(function(){
$('.colnum1:not(.selected)').eq(u).addClass('selected');
}, 1200 * u);
});
但出于某种原因,它并没有将类.selected
添加到所有元素中......它会跳过一些等等。
所以我想知道如何确保当我获得新的16个元素时.each
函数不会先抛出所有先前存在的元素(导致等待时间过长) ?
答案 0 :(得分:0)
无法选择所有元素的原因是它每次调用处理程序时都会重新评估术语$('.colnum1:not(.selected)')
。
让我们一步一步来看看。我们只关注第一栏。
首先评估$('.colnum1:not(.selected)')
,其中包含第一列中的所有4个块。然后迭代这些块并调用setTimeout
4次。到目前为止一切都很好。
然后它第一次调用处理程序。它再次评估$('.colnum1:not(.selected)')
,jQuery对象再次包含所有4个块。它会选择第一个(因为u=0
)并将selected
类添加到其中。
1200毫秒后,它再次调用处理程序。但是这一次, jQuery对象$('.colnum1:not(.selected)')
是不同的。由于.selected
过滤器,它不再包含第一个块。现在u=1
,所以$('.colnum1:not(.selected)').eq(u)
是这个新的缩短列表的第二个元素,即列中的第三个块。显然,你想要第二个。
有几种方法可以解决这个问题:
.eq(u)
更改为.eq(0)
。我不太喜欢这个。$('.colnum1:not(.selected)')
保存到变量,然后使用处理程序内的变量而不是再次评估CSS选择器。 jQuery对象将继续表示相同的4个元素,即使它们不再与选择器匹配。.each
处理程序接收当前HTML元素作为参数。不是作为jQuery对象,而是作为原始DOM元素。但是你可以通过调用$
使它成为一个jQuery对象,然后使用新的jQuery对象。像这样:
$('.colnum1').each(function(u, block){
setTimeout(function(){
$(block).addClass('selected');
}, 1200 * u);
});
this
关键字接收DOM元素。因此,在block
之前,您不必使用var block = this;
参数来编写setTimeout
。 (简单地将$(block)
替换为$(this)
可能无效 - 我不确定this
处理程序中setTimeout
的值是什么。它甚至可能依赖于浏览器我所知道的全部。)