您的假设是正确的:Working demo。
对于选择器匹配的每个对象,都会调用一次回调。会不会是 ID fall_content 的另一个元素已经隐藏了?因为如果是,那将立即调用 spring_content 动画,而无需等待 9 秒。
在引用的代码中,这不可能发生,因为选择器$('#fall_content') 永远不能产生多个元素。 (即使有 多个相同 ID 的元素,这不是有效的 HTML,jQuery 也只会产生这些元素中的第一个。
但是,从 cmets 中的代码可以看出,您使用了另一个选择器,它可能会产生多个元素。如果其中任何一个元素已被隐藏,则该元素将立即调用其回调。
要解决这个问题,您可以在选择器后添加not(':hidden');从集合中过滤掉任何已经隐藏的项目,这意味着所有剩余的项目将在 9 秒后调用淡入。
现在,除了您可能同时执行多个调用这一事实之外,您还引入了另一个可能的问题——如果选择器中的所有元素都被隐藏了。要求已经隐藏的元素在隐藏后调用回调,这完全不同于要求 没有元素 在它们被隐藏后调用回调:
// this will invoke the callback immediately
$('#already-hidden-element').animate({ opacity: 0 }, function() { ... });
// this will never invoke the callback
$('#id-that-does-not-exist').animate({ opacity: 0 }, function() { ... });
因此,如果这可能是您担心的问题(即使您认为它不会,因为需求可能会在以后发生变化,在这种情况下,这个问题将很难追踪),这是其中之一您可能想要反驳超时的情况:
var delay = 9000;
$('#bunch, #of, #IDs').animate({ opacity: 0 }, delay);
setTimeout(function() {
$('#spring_content').animate({ opacity: 1 }, 'fast');
}, delay);
现在保证您的超时只发生一次,并且总是在淡出开始后的 9 秒后发生。请注意,我们正在讨论的场景可能从一开始就隐藏了所有元素。在这种情况下,您可能不希望在显示 spring 内容之前等待 9 秒,而是希望立即将其淡入,就像原来的 animate 行为一样。在这种情况下,您必须有条件地设置延迟:
var elements = $('#bunch, #of, #IDs').not(':hidden');
var delay = elements.length == 0 ? 0 : 9000;
elements.animate({ opacity: 0 }, delay);
setTimeout(function() {
$('#spring_content').animate({ opacity: 1 }, 'fast');
}, delay);