逐个显示元素

3

我经常看到这样的问题,有多种解决方案。我正在尝试想出一些简短的可重复使用的东西。我的问题是,在给定的代码中,我是否需要clearTimeout()以及在哪里清除?另外,您会改进什么吗?这段代码对性能来说好还是坏?
http://jsfiddle.net/elclanrs/fQX8M/15/

var fade1by1 = function ($elms, props) {

    props = props || {};
    props.delay = props.delay || 1; // s
    props.speed = props.speed || 400; // ms
    props.ease = props.ease || 'linear';

    for (var i=0, d=0, l=$elms.length; i<l; i++, d+=props.delay*1000) {
        (function (i, d) {
            // Using `delay()` instead of `setTimeout()`
            // as Alexander suggested
            $elms.eq(i).delay(d).fadeIn(props.speed, props.ease);
        })(i, d);
    }
};

这其实很酷。如果我要添加更多功能,我会添加一个参数来设置单独的淡入淡出速度,以代替“slow”,并使用“slow”或200作为后备方案。 - James Hay
哦,是的,我最终会将这个制作成插件,但我只想看看最简单的情况是否可以改进。然后我会开始自定义。主要我想知道在这种情况下是否真的有必要使用 clearTimeout()... - elclanrs
我相信只有在计时器无限运行时才需要使用clearTimeout()。在这种情况下,它仅运行给定数量的元素,因此您不需要清除。当然,除非您随时添加停止按钮以停止下一个元素的到来。此外,这是一个带有ind_speed的快速版本(虽然您自己也可以得到它,但我只是想看看:p http://jsfiddle.net/fQX8M/7/ - James Hay
我更新了一些变量。你知道如何使用devtools或类似工具跟踪超时吗?也许可以用断点实现? - elclanrs
3个回答

0

我认为你不需要使用 window.clearTimeout,因为似乎你并不想停止动画。如果你还没有决定,那么考虑使用 .delay,它明确地使用了 window.setTimeout

var fade1by1 = function ($elms, speed) {
    speed = speed || 1; // Seconds
    for (var i=0, s=0, l=$elms.length; i<l; i++, s+=speed*1000) {
        $elms.eq(i).delay(s).fadeIn('slow');
    }
};

在这里查看它的运行情况。


是的,我尝试过了,但正如您所看到的,它不能正常工作http://jsfiddle.net/elclanrs/fQX8M/13/。 - elclanrs
我刚试了一下闭包函数,它能用。请看问题中的更新。那可以减少代码量。所以我想没有太多可以做来让它更轻。我的意思是已经足够轻,但因为我想在大规模实现这个功能,所以我担心性能问题。 - elclanrs
没有使用闭包函数,这对我起作用了。我在答案中放了一个链接到 jsfiddle。 - Alexander
哦,老兄,你说得对!谢谢。我会用这个制作一个小插件。即使处理大量对象,它也应该快速执行。 - elclanrs
你能提供一个你的方法的例子吗? - elclanrs
显示剩余2条评论

0

在我看来,你应该使用fadeIn函数的回调来完成这个操作。以下代码可以实现你所有的目标(请替换为你的新参数):

var customFade = function(parent, speed){
    $(':hidden:first', parent).fadeIn(speed, function(){
        customFade(parent, speed)
    });
}
$('button').click(function(){ customFade($('ul'), 1000); });

除非您想要在另一个仍在运行时开始淡出。 - James Hay

0

不要一次性设置所有操作并逐渐增加等待时间,另一种方法是将显示行为直接绑定到每个选定元素作为自定义事件,并在该绑定函数中包含一个固定的等待时间以及对“下一个”元素的自定义事件触发调用(如果存在)。要启动它,只需点燃第一个元素的引线。

因此,类似于这样:

var fadeCascade = function fadeCascade(your_selector, props) {
  props = props || {};
  props.delay = props.delay || 1; // s
  props.speed = props.speed || 2000; // ms
  props.ease = props.ease || 'linear';

  $(your_selector)
    .addClass('showme') // Being a little lazy here, but it works
                        // You could work out an inspection by attached event
    .bind('showme', function() { // custom event 
      $(this)
        .delay( props.delay * 1000 )
        .fadeIn(props.speed, props.ease, function() {
          $(this).nextAll('.showme:first').trigger('showme'); // jqueryish recursion
      });
    }).hide() // or just hide in initial css
  .first().trigger('showme'); // set the dominoes falling
};

并触发揭示:

fadeCascade('div.bar');​

如果您关心卫生问题,可以在进行操作时解除事件绑定并删除类。
例子:http://jsfiddle.net/redler/EKx6s/1/ 更新:增加了延迟,感谢@Alexander。

你是不是忘了加延迟了? - Alexander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接