0

我是 JS 新手,所以在这里放轻松。但我写了一个简单的幻灯片,它似乎运行得很慢。下面的代码大约需要 2-4 秒才能在我自己的机器上本地加载。想知道是什么导致了延迟。告诉我,谢谢!

function slideshow(){
    $("#1").animate({top: "50px",}, 500).delay(2000);
    $("#1").animate({top: "400px",}, 500);
    $("#2").animate({top: "50px",}, 500).delay(2000);
    $("#2").animate({top: "400px",}, 500);
    $("#3").animate({top: "50px",}, 500).delay(2000);
    $("#3").animate({top: "400px",}, 500);
    $("#4").animate({top: "50px",}, 500).delay(2000);
    $("#4").animate({top: "400px",}, 500);
    $("#5").animate({top: "50px",}, 500).delay(2000);
    $("#5").animate({top: "400px",}, 500);
    slideshow();
}

每个 ID 代表一个不同的图像。

4

5 回答 5

7

您的代码的一个问题是,因为其他答案似乎还没有谈到它,所以最后一行slideshow()调用本身是递归的,这将导致堆栈溢出。不要这样做:

function slideshow() {
   // animate code
   slideshow();
}

相反,如果您希望它重复运行,请在x毫秒后将setTimeout()函数的另一个执行排队:

function slideshow() {
   // animate code
   setTimeout(slideshow, 3500);
}

按照你的方式,没有一个功能真正完成。使用setTimeout(),每次调用都会slideshow()完成,然后在指定的延迟后运行一个单独的调用。我会让延迟足够大,以便在当前动画完成后发生下一次调用,否则你将排队越来越多的动画比它们运行的​​速度更快。

更新: jQuery 为每个元素维护单独的动画队列,这意味着您的五个元素上的动画将同时运行。其他一些答案已经提供了一次按顺序运行动画的方法,但这是我的做法:

$(window).on("load",function() {    
    // cache a jQuery object containing the elements to animate
    // (note you don't need their ids if you use their class)
    var $imgs = $('img.slideshow-image'),
        i = 0;

    function slideShow() {
       // start animation for "current" img
       $imgs.eq(i).show(1)
                  .animate({top: "50px",}, 500)
                  .delay(2000)
                  .animate({top: "400px",}, 500)
                  .hide(1, function() {
                     i = (i+1) % $imgs.length;
                     setTimeout(slideShow, 500);
                  });
    }    
    slideShow();    
});

工作演示:http: //jsfiddle.net/bARwb/

  • 我已经将代码包装在负载处理程序中,以消除对内联onload=属性的需要,并作为将代码保持在全局范围之外的一种方便方法(如果您这样做,请不要忘记onload="slideShow()"从您的 body 标签中删除)。
  • 我已经添加.show().hide()调用(一个持续时间,以便它们加入动画队列),以便 img 元素将display:none在动画之间,因为否则你的position:relative风格除了第一个之外你什么都看不到(但更改为position:absolute会阻止他们得到由他们的父母裁剪overflow:hidden)。
  • 当一个元素的动画完成时,回调从.hide()增量i指向下一个元素的索引(但检查它何时超过最后一个元素),然后用于setTimeout()为下一个元素排队动画。
于 2012-06-20T00:44:50.117 回答
2

你有一些重复,还有一些不正确的假设。

在 jQuery 中调用.animate时,可以指定动画完成时将调用的回调。这是放置“下一步”的地方。

所以在这个例子中:

  • 动画图像
  • 完成后,等待 2 秒
  • 2 秒后,为图像设置动画
  • 完成后,使用下一张图片调用该函数

这是它的样子

var images = ['#1', '#2', '#3', '#4', '#5'];

function slideshow(index){
    if (index >= images.length) {
        index = 0;
    }
    var image = images[index];
    $(image).animate({top: "50px",}, 500, function () {
        window.setTimeout(function () {
            $(image).animate({top: "400px",}, 500, function () {
                slideshow(index + 1);
            });
        }, 2000);
    });
}
于 2012-06-20T00:32:58.807 回答
0

除了代码中的故意延迟之外,我没有看到任何会导致加载缓慢的内容。它可能是页面的其余部分。在 JavaScript 幻灯片功能执行之前,我会检查您的图像有多大以及可能正在下载的任何其他文件。

附带说明一下,您从幻灯片功能中调用幻灯片很奇怪。

于 2012-06-20T00:26:39.990 回答
0

你可以尝试这样的事情:

var intervalValue = setInterval( "slideshow()", 2000 );
var slideshow_imageindex = 1;

function slideshow()
{
  //check if imageindex is greater than the number of images available (5 is an example)
  if (slideshow_imageindex > 5)
  {
    slideshow_imageindex = 1;
  }
  //hide image below, change image src, then move image so that it is visible again
  $("#1").animate({top: "400px",}, 500).attr('src','img/Slideshow-Audio-Trsfr'+slideshow_imageindex+'.png').animate({top: "50px",}, 500);
  //increase image index
  slideshow_imageindex++;
}

您只需要一个 img(我保留了您的“id=#1”img),并且每 2 秒图像被隐藏,它会更改并再次显示。只有你必须做的事情:命名图像,以便只有数字发生变化,例如:

img/Slideshow-Audio-Trsfr1.png
img/Slideshow-Audio-Trsfr2.png
img/Slideshow-Audio-Trsfr3.png
img/Slideshow-Audio-Trsfr4.png
img/Slideshow-Audio-Trsfr5.png

然后在函数内的“if”中使用图像数量。在意大利已经很晚了,希望我没有忘记任何事情:)

于 2012-06-20T00:38:38.677 回答
0

我的猜测是您将帧设置为 2 秒(2000 年)。尝试像 50 这样更快的速度,看看你看到了什么。我不确定这是帧延迟还是 500,但如果其中任何一个表示您在帧更改之间等待多长时间,那就太长了。

于 2012-06-20T00:21:32.313 回答