为幻灯片显示同步jQuery setInterval

时间:2012-06-15 16:05:27

标签: javascript jquery slideshow setinterval

我通过jQuery重复setInterval效果,创建了一个非常基本的幻灯片。但是,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);});​

工作示例为here

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

3 个答案:

答案 0 :(得分:4)

第一种方法: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();
});

这是第一种方法的fiddle

第二种方法:承诺

如果你想绝对保证在开始下一个动画时完成两个动画,你可以使用jQuery 1.6中的新promises。您可以在两个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();
});

对于简单的幻灯片演示,您可能不会发现太多差异。但是,通过承诺,您可以在保持同步的同时,使用时髦的时序制作更高级的转换序列。

这是该方法的fiddle

答案 1 :(得分:2)

将动画设置为在“相同”时间运行:

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

答案 2 :(得分:1)

因为我张开嘴,这是我提出的版本。我在其中添加了一个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/