2

我想通过顺序显示几个 png 来在页面加载时伪造一个简单的动画,每个 png 都会立即出现,但在下一个之前具有独特的、精确定时的延迟。使用最新版本的jQuery(编写时为1.4.2),它提供了延迟方法。我的第一个(脑死亡)冲动是:

$('#image1').show('fast').delay(800);
$('#image2').show('fast').delay(1200);
$('#image3').show('fast');

当然,所有这些都是同时出现的。jQuery doc 示例指的是被链接的单个项目,而不是处理多个项目。好的...使用来自 show() 的嵌套回调再试一次:

$('#image1').show('fast', function() {
    $('#image2').show('fast', function() {      
        $('#image3').show('fast', function() {      
        });
    });
});

看起来很丑(想象一下做 10 次,也想知道处理器会受到什么影响)但是嘿,它是按顺序工作的!虽然没有延迟。所以......在 show() 之后使用它的回调函数链接 delay() (甚至不确定它是否支持):

$('#image1').show('fast').delay(800, function() {
    $('#image2').show('fast').delay(1200, function() {      
        $('#image3').show('fast');
    });
});

嗯。我认为可能发生的相反结果:回调有效,但仍然没有延迟。那么......我应该使用队列和延迟的某种组合而不是嵌套回调吗?例如,队列的 jQuery 文档示例再次仅使用一个元素。猜测这将涉及使用自定义队列,但我不确定如何实现这一点。或者也许我错过了一个简单的方法?(对于一个简单的问题!)

4

5 回答 5

3

如果它们在一起,您可以简化它:

function showNext(img) {
  //show, find next image, repeat, when next doesn't find anything, it'll stop
  img.show('fast', function() { showNext($(this).next('[id^=image]')); });
}
//Call the first image to start the chain
showNext($("#image1"));

如果它们相距较远,只需将该.next()选择器调整为如何找到下一张图像,或者您可以为它们全部分配一个类,等等......但是您可以遍历下一个作品。

于 2010-03-02T14:13:28.377 回答
2

在这里疯狂猜测,但是呢?

$('#image1').show('fast', function() {
    $('#image2').delay(800).show('fast', function() {      
        $('#image3').delay(1200).show('fast', function() {      
        });
    });
});
于 2010-03-02T14:06:50.860 回答
0

可能有一种流行的方式可以直接使用 jQuery 执行此操作,但我很想使用简单的数组和简单的超时机制来执行此操作。

var toShow = ["image1", "image2", "image3", ... ], index = 0;
setTimeout(function() {
  $('#' + toShow[index++]).show('fast');
  if (index >= toShow.length) return;
  setTimeout(arguments.callee, 1000);
}, 1000);

如果它们不应该一直相同,您也可以将“延迟”值放入数组中:

var toShow = [ {img: "image1", delay: 800}, {img: "image2", delay: 1200}, ... ],
  index = 0;
setTimeout(function() {
  $('#' + toShow[index].img).show('fast');
  if (index >= toShow.length) return;
  setTimeout(arguments.callee, toShow[index].delay);
}, toShow[0].delay);

编辑这很有趣 :-) 如果您愿意,可以将图像数组构建为 jQuery 对象——换句话说,您可以将图像放入 HTML 中,然后使用 jQuery 选择器“查找”它们。至于延迟值,好吧,如果你想让延迟成为每个图像的事情,你可以使用 jQuery“元数据”插件将它编码到图像类名称中,或者如果你不需要任何东西,可以使用更简单的 hack详细说明其他内容:

var toShow = $('img.showMeSlowly'), index = 0, getDelay = function(img) {
  var delay = 1000;
  $(img).attr('class').replace(/.*\bdelay:(\d+)\b.*/, function(_, ds) {
    delay = parseInt(ds, 10);
  });
  return delay;
};

setTimeout(function() {
  toShow.eq(index++).show('fast');
  if (index >= toShow.length) return;
  setTimeout(arguments.callee, getDelay(toShow.get(index)));
}, getDelay(toShow.get(0)));
于 2010-03-02T14:09:22.543 回答
0

使用队列非常简单:

var imgs = ['#image1','#image2','#image3',...];

function showNext() {
  var img = imgs.shift();
  if (img) $(img).show('fast', showNext);  
}

showNext(); // start
于 2010-04-30T03:52:11.343 回答
0

我对这里给出的奇怪答案感到有点惊讶。这个问题有点老了,但我想其他人仍然会搜索并找到这个,所以我们走吧:

首先,delay() 不接受回调函数。如果要延迟任何动作,则必须将 delay() 放在动作前面的点符号链中

$('#image1').delay(800).show('fast');

这将等待 0.8 秒,然后快速显示图像(持续时间“快速”= 0.2 秒)。

其次,如果您有多个要同时运行的操作,您只需一个接一个地编写它们:

$('#image1').show('fast');
$('#image2').show('fast');

这样它们都会同时启动,所以上面的代码会并行播放#image1和#image2的淡入动画!

如果您想以不同的延迟开始多个动画,您可以结合这两种策略并简单地执行以下操作:

$('#image1').show('slow');
$('#image2').delay(1000).show('slow');
$('#image3').delay(1600).show('slow');
$('#image4').delay(2000).show('slow');

根据延迟和持续时间,这允许您连续播放动画,每个动画之间有间隙(2 个在 1 完成后延迟开始),连续(3 个在 2 刚刚完成时开始,因为持续时间“慢”是 600 毫秒) 并延迟但有重叠(4 开始,而 3 仍在运行)。您所要做的就是调整您的延迟和持续时间。这实际上是您问题的答案,也是做您想做的最通用的方法。

关于回调函数的一句话:这可用于 show()、animate() 和其他几种方法(但不是延迟,因为你试过了!)如果你想在动画完成后做更复杂的事情,主要需要它完成的。但要小心:当您的选择器匹配多个元素时,例如$('#image1, #image2'),回调将被调用多次(!)次 - 为您集合中的每个元素调用一次。这可能会导致非常意外的结果(快速提示:查找有关 jQuery 的 when()/then() 方法的信息以避免这种情况)。

最后,为了完整起见,如果您只是想在同一个元素上运行多个动画- 一个动画一个接一个,并且中间可能有延迟 - 您可以简单地做......

$('#image1').show('fast').hide('slow').delay(500).show('slow').hide('fast');

这将快速显示图像,然后将其缓慢隐藏,然后等待半秒钟,然后将其缓慢显示,然后将其快速隐藏。

于 2013-10-25T20:58:22.497 回答