我有通过CSS3动画制作的元素列表,如下所示:
.anim-slide-left {
animation: anim-slide-left 0.8s ease forwards;
-webkit-animation: anim-slide-left 0.8s ease forwards;
}
@-webkit-keyframes anim-slide-left {
0% {
transform: translateX(-500px);
-webkit-transform: translateX(-500px);
opacity: 0;
}
100% {
transform: translateX(0);
-webkit-transform: translateX(0);
opacity: 1;
}
}
/* there are more, but very similar */
当页面加载时,js应仅为具有特殊类别的可见元素设置动画'动画':
$(function() {
var $window = $(window);
var $toAnimate = $('.animate');
animate();
// check if element is on the viewport
function isElementVisible(elementToBeChecked)
{
var TopView = $(window).scrollTop();
var BotView = TopView + $(window).height();
var TopElement = elementToBeChecked.offset().top;
return ((TopElement <= BotView) && (TopElement >= TopView));
}
// add css animation class
function animate()
{
$toAnimate.each(function(i, el)
{
var $el = $toAnimate.eq(i);
if ($el.length && isElementVisible($el))
{
// remove already visible elements
$toAnimate.splice(i, 1);
// setting up animation effect
$el.addClass( $el.data('effect') );
$el.removeClass('animate');
}
});
}
});
现在问题就在于此。只检查每个第二个元素是否可见,如下所示:
但它应该是这样的:
仅当页面向下滚动时,其他元素才会生成动画,其中包含:
$window.scroll( function()
{
animate();
});
如何遍历此场景中的每个元素?
编辑:
注意@ T.J。 Crowder评论我用@charlietfl建议的过滤函数修改了animate函数:
$('.animate').filter( function( idx ) {
if( isElementVisible($(this)) )
{
$(this).addClass( $(this).data('effect') );
$(this).removeClass('animate');
}
});
它工作得很好:)谢谢你们。
答案 0 :(得分:5)
那里有几个问题:
您正在修改您正在迭代的集合($toAnimate
),并且您正在使用不断增加的索引从该集合中检索项目。所以很自然地,如果你删除一个,从那时起你的索引就会被关闭。
splice
不是官方的jQuery方法。它没有记录,可能随时消失。 (jQuery对象不是数组;它们只是类似数组。)
据我所知,jQuery会no guarantees关于each
如果你在迭代的集合中添加或删除条目会做什么(不像JavaScript& #39; s forEach
)。
由于您拥有splice
和来自forEach
的迭代保证,因此您可以使用.get
将$toAnimate
设为实际数组:
var $toAnimate = $('.animate').get();
// ---------------------------^^^^^^
......然后:
function animate()
{
$toAnimate.forEach(function(el)
{
var $el = $(el);
if (isElementVisible($el))
{
// remove already visible elements
$toAnimate.splice(i, 1);
// setting up animation effect
if( $el.data('effect') == 'anim-bar' ) animateBar($el);
else $el.addClass( $el.data('effect') );
$el.removeClass('animate');
}
});
}
答案 1 :(得分:1)
您正在从正在迭代的数组中删除项目,因此下一个项目将取代当前项目。当您转到下一个项目时,将跳过一个项目。
如果从最后循环遍历数组,删除项目不会影响循环中的项目:
function animate()
{
for (var i = $toAnimate.length - 1; i >= 0; i--)
{
var $el = $toAnimate.eq(i);
if ($el.length && isElementVisible($el))
{
// remove already visible elements
$toAnimate.splice(i, 1);
// setting up animation effect
if( $el.data('effect') == 'anim-bar' ) animateBar($el);
else $el.addClass( $el.data('effect') );
$el.removeClass('animate');
}
});
}