多元素 jQuery 动画问题
Multi-element jQuery animation issue
我正在尝试循环选择多个元素并在鼠标悬停在父区域上时移动它们。这工作得很好,但每次动画循环通过第一个元素(子元素)时移动得比其他元素快。 ??? JSFiddle Example
HTML:
<div id="menuContent">
<button id="btn1" class="mainButton" left="0"/>
<button id="btn2" class="mainButton" left="0"/>
<button id="btn3" class="mainButton" left="0"/>
</div>
jQuery:
$("#menuContent").hover(function () {
loop();
}
, function () {
stop();
}
);
function stop() {
$(".mainButton").stop();
}
function loop() {
$(".mainButton").stop().animate({ left: "+=20"}, 100, 'linear', function () { loop(); });
}
来自文档:
complete
A function to call once the animation is complete, called once per matched element.
当您调用 animate
时,它会启动 3 个动画。第一个元素的动画首先开始和结束。然后它的 complete
被调用,你停止并开始所有动画,尽管其中一些还没有完成。
考虑这个例子 (Fiddle):
function loop() {
$('.mainButton').stop().animate({
left: '+=1'
}, 1, 'linear', function() {
loop();
});
}
只有一个圆圈会移动,因为其他圆圈没有时间间隔。
您可以使用 promises 使其工作 (Fiddle):
$('#menuContent').hover(function() {
$('.mainButton').data('run', true);
loop();
}, function() {
$('.mainButton').data('run', false);
});
function loop() {
if (!$('.mainButton').data('run')) return;
$('.mainButton').animate({left: '+=10'}, 100, 'linear').promise().done(loop);
}
Danil Speransky 是正确的。但是,animate 函数有一个选项参数,允许动画不 运行 在刚性队列中。
`$(".mainButton").animate({ left: "+=20"},{queue: false}, 100, 'linear', function () { loop();});`
查看 queue:false here 的文档。
如果 jquery 集合中的一个元素的动画完成,将调用您的完整处理程序。因此,当第一个元素完成时,调用循环并停止其他元素的动画。最好使用 promise 和 done 并在集合中保存动画状态:
$("#menuContent").hover(function () {
start();
}, function () {
stop();
});
function start() {
$(".mainButton").data('stopped', false);
loop();
}
function stop() {
$(".mainButton").data('stopped', true).stop();
}
function loop() {
var $mainButtons = $(".mainButton").stop();
if(!$mainButtons.data('stopped'))
$mainButtons.animate({ left: "+=20"}, 100, 'linear').promise().done(loop);
}
这是一个有效的 fiddle (https://jsfiddle.net/wotfLyuo/5/)
你的里程可能会有所不同,但做这两件事似乎很有帮助:
首先,为 .mainButton
个元素存储 jQuery 对象:
var $mainButton = $('.mainButton')
其次,使left
增加更多并增加延迟:
$mainButton.stop().animate(
{ left: "+=1000"},
5000,
'linear',
function() { loop() })
你可以多玩玩这些数字,看看你是否会获得更好的表现。
我正在尝试循环选择多个元素并在鼠标悬停在父区域上时移动它们。这工作得很好,但每次动画循环通过第一个元素(子元素)时移动得比其他元素快。 ??? JSFiddle Example
HTML:
<div id="menuContent">
<button id="btn1" class="mainButton" left="0"/>
<button id="btn2" class="mainButton" left="0"/>
<button id="btn3" class="mainButton" left="0"/>
</div>
jQuery:
$("#menuContent").hover(function () {
loop();
}
, function () {
stop();
}
);
function stop() {
$(".mainButton").stop();
}
function loop() {
$(".mainButton").stop().animate({ left: "+=20"}, 100, 'linear', function () { loop(); });
}
来自文档:
complete
A function to call once the animation is complete, called once per matched element.
当您调用 animate
时,它会启动 3 个动画。第一个元素的动画首先开始和结束。然后它的 complete
被调用,你停止并开始所有动画,尽管其中一些还没有完成。
考虑这个例子 (Fiddle):
function loop() {
$('.mainButton').stop().animate({
left: '+=1'
}, 1, 'linear', function() {
loop();
});
}
只有一个圆圈会移动,因为其他圆圈没有时间间隔。
您可以使用 promises 使其工作 (Fiddle):
$('#menuContent').hover(function() {
$('.mainButton').data('run', true);
loop();
}, function() {
$('.mainButton').data('run', false);
});
function loop() {
if (!$('.mainButton').data('run')) return;
$('.mainButton').animate({left: '+=10'}, 100, 'linear').promise().done(loop);
}
Danil Speransky 是正确的。但是,animate 函数有一个选项参数,允许动画不 运行 在刚性队列中。
`$(".mainButton").animate({ left: "+=20"},{queue: false}, 100, 'linear', function () { loop();});`
查看 queue:false here 的文档。
如果 jquery 集合中的一个元素的动画完成,将调用您的完整处理程序。因此,当第一个元素完成时,调用循环并停止其他元素的动画。最好使用 promise 和 done 并在集合中保存动画状态:
$("#menuContent").hover(function () {
start();
}, function () {
stop();
});
function start() {
$(".mainButton").data('stopped', false);
loop();
}
function stop() {
$(".mainButton").data('stopped', true).stop();
}
function loop() {
var $mainButtons = $(".mainButton").stop();
if(!$mainButtons.data('stopped'))
$mainButtons.animate({ left: "+=20"}, 100, 'linear').promise().done(loop);
}
这是一个有效的 fiddle (https://jsfiddle.net/wotfLyuo/5/)
你的里程可能会有所不同,但做这两件事似乎很有帮助:
首先,为 .mainButton
个元素存储 jQuery 对象:
var $mainButton = $('.mainButton')
其次,使left
增加更多并增加延迟:
$mainButton.stop().animate(
{ left: "+=1000"},
5000,
'linear',
function() { loop() })
你可以多玩玩这些数字,看看你是否会获得更好的表现。