同步 jQuery setInterval 用于幻灯片放映

Synchronizing jQuery setInterval for slideshow

本文关键字:幻灯片 用于 jQuery setInterval 同步      更新时间:2023-09-26

我通过用setInterval重复jQuery效果创建了一个非常基本的幻灯片。但是,在setInterval的每个周期之后,时间不匹配。几个循环后,它会导致两个平行滑动效果出现明显的不匹配。

代码是

$(document).ready(function(){
var frontslides =$("#first li").length,
    slideTime=500,
    slideCycle=parseInt(slideTime*frontslides);
function frontSlide(){
    $("#first li").each(function(n){
        $(this).delay(slideTime*n).fadeIn(400).fadeOut(100);
        $("#second li").eq(n).delay(slideTime*n).fadeIn(400).fadeOut(100);
    });}
frontSlide();setInterval(frontSlide, slideCycle);});​

工作示例在这里

为了节省您的宝贵时间,它的速度很快,但它发生在任何速度上。几个循环后,您可以看到左右幻灯片不再同步。

第一种方法:setTimeout

您可以在单独的函数中将过渡移动到下一张幻灯片,并使用 setTimeout 调用它。然后,您只需将幻灯片编号存储在变量中,并在每次函数调用后递增它。

$(document).ready(function(){
    var firstSlides = $("#first li"),
        secondSlides = $("#second li"),
        nbSlides = firstSlides.length,
        slideTime = 500,
        nextSlide = 0;
    function slideshow() {
        firstSlides.eq(nextSlide).fadeIn(400).fadeOut(100);
        secondSlides.eq(nextSlide).fadeIn(400).fadeOut(100);
        nextSlide = (nextSlide+1) % nbSlides;
        setTimeout(slideshow, slideTime);
    }
    slideshow();
});

这是第一种方法的小提琴。

第二种方法:承诺

如果你想绝对保证在启动下一个动画时两个动画都完成,你可以使用 jQuery 1.6 中的新承诺。您可以在两个 jQuery 对象上调用 $.promise() 来获取一个承诺,该承诺将在该元素的所有动画完成后解析。然后,您可以使用$.when(promises...)设置主承诺,当解析所有给定的承诺时,将解析该主承诺并设置then处理程序。

$(document).ready(function(){
    var firstSlides = $("#first li"),
        secondSlides = $("#second li"),
        nbSlides = firstSlides.length,
        fadeInTime = 400,
        fadeOutTime = 100,
        nextSlide = 0;
    function slideIn() {
        var p1 = firstSlides.eq(nextSlide).fadeIn(400).promise();
        var p2 = secondSlides.eq(nextSlide).fadeIn(400).promise();
        $.when(p1, p2).then(slideOut);
    }
    function slideOut() {
        var p1 = firstSlides.eq(nextSlide).fadeOut(100).promise();
        var p2 = secondSlides.eq(nextSlide).fadeOut(100).promise();
        nextSlide = (nextSlide+1) % nbSlides;
        $.when(p1, p2).then(slideIn);
    }
    slideIn();
});

对于简单的幻灯片,您可能不会注意到太大的区别。但是,有了承诺,您可以制作更高级的过渡序列,同时仍然保持同步。

这是这种方法的小提琴。

将动画设置为在"同一"时间运行:

function frontSlide(){
    $("#first li").each(function(n){
        var _ = $(this);
        setTimeout(function() {
            _.fadeIn(400).fadeOut(100);
            $("#second li").eq(n).fadeIn(400).fadeOut(100);
        }, slideTime*n);
    });
}

既然我开口了,这就是我想出的版本。我在其中添加了一个blocked标志,以指示效果循环当前正在运行,希望可以防止脚本溢出自身。我还添加了一个 factor 值,以便在确实发生溢出时,它会更快地循环,以保持循环未中断的外观。

如果您有任何其他问题,请告诉我。这很简单。

$(document).ready(function() {
    var $sel = $('#left, #right').find('li:first-child'),
        slidetime = 200,
        timein = 400,
        timeout = 100,
        blocked = false;
    var fadeout = function() {
        $sel.fadeOut(timeout, next);
    };
    var next = function() {
        if ($sel.is(':last-child')) {
            $sel = $sel.siblings(':first-child');
        } else {
            $sel = $sel.next();
        }
        blocked = false;
    };
    (function slider() {
        var factor = .2;
        if (!blocked) {
            factor = 1;
            blocked = true;
            $sel.fadeIn(timein, fadeout);
        }
        setTimeout(slider, slidetime * factor);
    })();
});​

http://jsfiddle.net/j63vH/