$ .each功能无法正常工作

时间:2012-06-18 09:48:05

标签: javascript jquery

最终我正在尝试创建一个定时幻灯片放映,淡入淡出图像。我无法弄清楚的是为什么我的$ .each函数为数组的每个索引完成循环,而只是循环最后一个图像七次。

这是我的代码......

<script>
$(document).ready(function(){
    var image1 = "<img width='600' height='400' src='images/image1.jpg' />";
    var image2 = "<img width='600' height='400' src='images/image2.jpg' />";
    var image3 = "<img width='600' height='400' src='images/image3.jpg' />";
    var image4 = "<img width='600' height='400' src='images/image4.jpg' />";
    var image5 = "<img width='600' height='400' src='images/image5.jpg' />";
    var image6 = "<img width='600' height='400' src='images/image6.jpg' />";
    var image7 = "<img width='600' height='400' src='images/image7.jpg' />";
    var image8 = "<img width='600' height='400' src='images/image8.jpg' />";

    var imageArray = new Array(image1, image2, image3, image4, image5, image6, image7, image8);
    $.each(imageArray, function(key, value){
        $('#slide').html(value);
        $('#slide').hide().fadeIn('slow').fadeOut('slow');
    });
});
</script>

同样,最终发生的事情是最后一张图像在消失之前淡入淡出7次。先谢谢你们。

6 个答案:

答案 0 :(得分:2)

这是因为你的循环不等待动画完成。它将所有动画命令一个接一个地保留在队列中。因此,最好给回调以检查动画何时完成,然后更改图像(通过继续循环) 否则你必须像Thilo建议的那样做。

答案 1 :(得分:2)

我认为您的问题是,在fadeInfadeOut正在做他们的事情时,JavaScript执行不会暂停。

您的each电话会执行此操作:

  1. #slide的HTML设置为image1
  2. 隐藏#slide
  3. 开始淡出#slide
  4. 立即将#slide的HTML设置为image2(因为它不等待fadeIn完成),覆盖image1
  5. 再次开始淡化#slide
  6. 等等。

    为了得到你想要的结果,你需要一个递归函数(即一个自己调用的函数),而不是你的each调用。此函数需要将回调函数传递给fadeInfadeOut - 当fadeInfadeOut执行完毕后,将调用这些函数。

    E.g。

    function fadeImagesInAndOut(imageArray, imageIndex) {
        $('#slide').html( imageArray(imageIndex) );
    
        $('#slide').hide().fadeIn('slow', function () {
    
            $('#slide').fadeOut('slow', function () {
    
                if (imageIndex < imageArray.length) {
                    fadeImagesInAndOut(imageArray, imageIndex + 1);
                }
            });
        });
    }
    
    fadeImagesInAndOut(imageArray, 0);
    

答案 2 :(得分:1)

您将$('#slide')html设置为8次,每次都重写一次。可能你打算将每个图像附加到它?

$('#slide').append( $(value) );

另外,你在#slide上调用hide()8次。这是你想要的吗?

编辑:未经测试,但让您了解如何使用回调

var imgArray = new Array(...)

var doAnimate = function(key){
   if(!value = imgArray[key]) return;
   $('#slide').html(value);
   $('#slide').hide().fadeIn('slow').fadeOut('slow', function(){
       doAnimate(key++);
   });
}

doAnimate(0);

答案 3 :(得分:1)

异步执行的神奇之处。

按时间顺序排列的事件:

    $('#slide').html(image1);
    $('#slide').hide();
    #   fadeIn('slow').fadeOut('slow'); will happen some time later
    $('#slide').html(image2);
    $('#slide').hide();
    #   fadeIn('slow').fadeOut('slow'); will happen some time later
    $('#slide').html(image3);
    $('#slide').hide();
    #   fadeIn('slow').fadeOut('slow'); will happen some time later

循环将进入第二个(和第三个等等)迭代,在第一个动画完成之前重置图像直到它是最后一个。

答案 4 :(得分:1)

事情是动画是异步执行的。在代码中执行命令的顺序是:

  1. $('#slide').html设为第1张图片。
  2. 让jQuery开始对象的动画。动画尚未开始。
  3. $('#slide').html设为第2张图片。
  4. 要求另一个动画。
  5. ...
  6. 最后一次要求动画。
  7. 您的功能已完成。浏览器开始重绘页面并触发超时事件。您的容器已隐藏,其html指的是最后一张图片。
  8. jQuery为您的容器设置动画。
  9. 只有在动画结束后才需要更改容器的html。这是一个例子:

    $(document).ready(function(){
      //populate imageArray 
      function animate_one(index) {
        if (index >= imageArray.length) return;
        $('#slide').html(imageArray[index]);
        $('#slide').hide().fadeIn('slow').fadeOut('slow', function() {
          animate_one(index+1);
        });
      }
      animate_one(0);
    });
    

    Fiddle

答案 5 :(得分:0)

如何做到这一点(具有漂亮的淡入淡出效果):

jsBin demo

将一个图像放入DIV中,而不是将数组预先一个新图像循环到DIV中。使用:last选择器淡出旧图像(并删除)。

var images = ['image1.jpg','image2.jpg','image3.jpg'];       // your images

var c = 0;                                                   // set the first image
$('#slide').prepend( '<img src="'+ images[c] +'" />' );      // prepend one

function loop(){ 
    $('#slide').prepend( '<img src="'+ images[c++ % images.length] +'" />' );    
       $('#slide img:last').delay(1000).fadeTo(700,0,function(){
            $(this).remove();                                // remove last one
            loop();
       });  
}
loop();

在你的CSS中确保你的图像绝对定位。