Javascript 只迭代第二个元素

Javascript 只迭代第二个元素,javascript,jquery,html,css,css-animations,Javascript,Jquery,Html,Css,Css Animations,我有通过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); -

我有通过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应仅使用特殊类“animate”设置可见元素的动画:

$(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');
            } 
        });
    }
});
如何迭代该场景中的每个元素

编辑:

注意到@T.J.Crowder的评论,我使用@charlietfl建议的过滤函数修改了动画函数:

$('.animate').filter( function( idx ) {
    if( isElementVisible($(this)) )
    {
        $(this).addClass( $(this).data('effect') );
        $(this).removeClass('animate');
    }
});

很好:)谢谢大家。

有几个问题:

  • 您正在修改正在迭代的集合(
    $toAnimate
    ),并且正在使用不断增加的索引从该集合中检索项目。所以很自然,如果你去掉一个,从那以后你的索引就会关闭

  • splice
    不是正式的jQuery方法。它没有文件记录,随时可能消失。(jQuery对象不是数组;它们只是数组一样。)

  • 据我所知,jQuery提供了当您在正在迭代的集合中添加或删除条目时,
    每个
    将做什么(不同于JavaScript的
    forEach

  • 由于您有
    splice
    和来自
    forEach
    的迭代保证,您可以使用以下方法使
    $toAnimate
    成为实际数组:

    …然后:

    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');
            } 
        });
    }
    

    您正在从正在迭代的数组中删除项,因此下一项将取代当前项。当您转到下一项时,将跳过一项

    如果从末尾循环数组,则删除项目不会影响循环中的后续项目:

    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');
            } 
        });
    }
    

    好的,当您从正在循环的集合中删除条目(
    $toAnimate
    )时,很可能会发生类似的情况。它没有文件记录,随时可能消失。(jQuery对象不是数组;它们只是类似数组的。)据我所知,jQuery说明了如果您在正在迭代的集合中添加或删除条目,每个将做什么(不同于JavaScript的
    forEach
    )。您可能需要
    filter()
    而不是使用
    each()
    splice()
    splice()
    会破坏原始集合,而
    filter()
    则会破坏原始集合not@T.J.Crowder谢谢你的评论,你完全正确,因此我相信@charlietfl answer是使用
    过滤器
    功能的最佳选择。谢谢你,这很有效,但我也必须注意其他评论,比如jquery兼容性。
    
    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');
            } 
        });
    }
    
    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');
            } 
        });
    }