【问题标题】:only every second element is iterated仅迭代每个第二个元素
【发布时间】:2015-08-02 20:56:10
【问题描述】:

我有通过 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');
            } 
        });
    }
});

现在问题来了。只有每隔一个元素被检查为可见,如下所示:

但应该是这样的:

其余元素仅在页面向下滚动时才会进行动画处理,其中:

$window.scroll( function()
{
    animate();
});

如何遍历这个场景中的每个元素?

编辑:

注意到@T.J. Crowder cmets 我用@charlietfl 建议的过滤功能修改了动画功能:

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

它工作得很好:) 谢谢你们。

【问题讨论】:

  • 好吧,当您从正在循环的集合中删除条目时,可能会发生类似的事情 ($toAnimate)。
  • 还要注意splice不是官方的jQuery方法。它是无证的,可能随时消失。 (jQuery 对象不是数组;它们只是 类数组。)
  • And 据我所知,jQuery 使 no guarantees 关于 each 在您正在迭代的集合中添加或删除条目时会做什么(不像 JavaScript 的 forEach)。
  • 您可能想要filter() 而不是使用each()splice()splice() 对原始收藏具有破坏性,而 filter() 则没有
  • @T.J.Crowder 谢谢你的 cmets,你是绝对正确的,所以我相信 @charlietfl 的答案是最好的 filter 函数。

标签: javascript jquery html css css-animations


【解决方案1】:

有几个问题:

  1. 您正在修改您正在迭代的集合 ($toAnimate),并且您正在从该集合中检索具有不断增加的索引的项目。所以很自然,如果你删除一个,从那时起你的索引就会关闭。

  2. splice 不是官方的 jQuery 方法。它是无证的,可能随时消失。 (jQuery 对象不是数组;它们只是 类数组。)

  3. 据我所知,jQuery 使no guarantees 关于each 在您正在迭代的集合中添加或删除条目时会做什么(与 JavaScript 的 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');
        } 
    });
}

【讨论】:

    【解决方案2】:

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

    如果从末尾循环遍历数组,删除项目不会影响循环后面的项目:

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

    【讨论】:

    • 行得通,谢谢,但我也必须注意其他 cmets,例如 jquery 兼容性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 2012-09-25
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多