如何使用 JQuery 链接或排队自定义函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1095263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I chain or queue custom functions using JQuery?
提问by orandov
I have multiple functions the do different animations to different parts of the HTML. I would like to chain or queue these functions so they will run the animations sequentially and not at the same time.
我有多个函数可以对 HTML 的不同部分执行不同的动画。我想链接或排队这些函数,以便它们按顺序而不是同时运行动画。
I am trying to automate multiple events in sequence to look like a user has been clicking on different buttons or links.
我正在尝试按顺序自动执行多个事件,以看起来用户一直在单击不同的按钮或链接。
I could probably do this using callback functions but then I would have to pull all of the animations from the different functions and regroup in the right pattern.
我可能可以使用回调函数来做到这一点,但是我必须从不同的函数中提取所有动画并以正确的模式重新组合。
Does the jquery "queue" help? I couldn't understand the documentationfor the queue.
jquery“队列”有帮助吗?我无法理解队列的文档。
Example, JQuery:
示例,JQuery:
function One() {
$('div#animateTest1').animate({ left: '+=200' }, 2000);
}
function Two() {
$('div#animateTest2').animate({ width: '+=200' }, 2000);
}
// Call these functions sequentially so that the animations
// in One() run b/f the animations in Two()
One();
Two();
HTML:
HTML:
<div id="animatetest" style="width:50px;height:50px;background-color:Aqua;position:absolute;"></div>
<div id="animatetest2" style="width:50px;height:50px;background-color:red;position:absolute;top:100px;"></div>
Thanks.
谢谢。
EDIT: I tried it with timersbut I thought there is a better way to do it.
编辑:我用计时器尝试过,但我认为有更好的方法来做到这一点。
EDIT #2:
编辑#2:
Let me be more specific. I have multiple functions bound to click & hover events on different elements of the page. Normally these functions have nothing to do with each other ( they don't reference each other). I would like to simulate a user going through these events without changing the code of my existing functions.
让我说得更具体一点。我有多个功能绑定到页面不同元素上的单击和悬停事件。通常这些函数彼此无关(它们不相互引用)。我想模拟用户在不更改现有函数的代码的情况下经历这些事件。
回答by Yehuda Katz
The jQuery Queue code is not as well documented as it could be, but the basic idea is this:
jQuery Queue 代码的文档记录并不完整,但基本思想是这样的:
$("#some_element").queue("namedQueue", function() {
console.log("First");
var self = this;
setTimeout(function() {
$(self).dequeue("namedQueue");
}, 1000);
});
$("#some_element").queue("namedQueue", function() {
console.log("Second");
var self = this;
setTimeout(function() {
$(self).dequeue("namedQueue");
}, 1000);
});
$("#some_element").queue("namedQueue", function() {
console.log("Third");
});
$("#some_element").dequeue("namedQueue");
If you run this code, you will see "First" in the console, a pause of 1s, see "Second" in the console, another pause of 1s, and finally see "Third" in the console.
如果你运行这段代码,你会在控制台看到“First”,暂停1s,在控制台看到“Second”,又暂停1s,最后在控制台看到“Third”。
The basic idea is that you can have any number of named queues bound to an element. You remove an element from the queue by calling dequeue
. You can do this yourself manually as many times as you want, but if you want the queue to run automatically, you can simply call dequeue
inside the queued up function.
基本思想是您可以将任意数量的命名队列绑定到一个元素。您可以通过调用从队列中删除一个元素dequeue
。您可以根据需要手动多次手动执行此操作,但如果您希望队列自动运行,您只需dequeue
在排队函数内部调用即可。
Animations in jQuery all run inside a queue called fx
. When you animate an element, it automatically adds the new animation on the queue and calls dequeue if no animations are currently running. You can insert your own callbacks onto the fx
queue if you wish; you will just need to call dequeue
manually at the end (as with any other queue use).
jQuery 中的动画都在名为fx
. 当您为元素设置动画时,它会自动将新动画添加到队列中,如果当前没有动画正在运行,则调用 dequeue。fx
如果您愿意,您可以将自己的回调插入到队列中;您只需要dequeue
在最后手动调用(与任何其他队列使用一样)。
回答by Spencer Ruport
I'd create an array of functions and add every function you want to queue to it.
我会创建一个函数数组并将您想要排队的每个函数添加到其中。
Then I'd append a function call which loops through the array and calls each function to the event through jQuery.
然后我会附加一个函数调用,它循环遍历数组并通过 jQuery 将每个函数调用到事件。
You could probably create a very simple plugin for jQuery that could handle this internally as well.
您可能可以为 jQuery 创建一个非常简单的插件,它也可以在内部处理这个问题。
回答by geowa4
On one of my web projects, I had to perform various sequences of actions depending on what event fired. I did this using callbacks (something like the Visitor pattern). I created an object to wrap any function, or group of actions. Then I would queue those wrappers; an array works fine. When the event fired, I would iterate over the array, calling my object's specialized method that took a callback. That callback triggered my iteration to continue.
在我的一个 Web 项目中,我必须根据触发的事件执行各种操作序列。我使用回调(类似于访问者模式)做到了这一点。我创建了一个对象来包装任何函数或一组操作。然后我会将这些包装器排队;数组工作正常。当事件触发时,我将遍历数组,调用我的对象的特殊方法,该方法接受回调。该回调触发了我的迭代继续。
To wrap a function, you need knowledge of the apply function. The apply function takes an object for scope and an array of arguments. That way you don't need to know anything about the functions you are wrapping.
要包装函数,您需要了解apply 函数。apply 函数接受一个对象作为作用域和一个参数数组。这样你就不需要知道你正在包装的函数的任何信息。
回答by Skaumo
How about just something of the like?
类似的东西怎么样?
var f1 = function() {return $(SELECTOR1).animate({ 'prop': 'value' }, 1000)};
var f2 = function() {return $(SELECTOR2).animate({ 'prop': 'value' }, 1000)};
var f3 = function() {return $(SELECTOR3).animate({ 'prop': 'value' }, 1000)};
$.when(f1).then(f2).then(f3);
回答by marcc
Assuming you want to keep One
and Two
as separate functions,
you could do something like this:
假设您想保留One
和Two
作为单独的功能,您可以执行以下操作:
function One(callback) {
$('div#animateTest1').animate({ left: '+=200' }, 2000,
function(e) { callback(); });
}
function Two() {
$('div#animateTest2').animate({ width: '+=200' }, 2000);
}
// Call these functions sequentially so that the animations
// in One() run b/f the animations in Two()
One(Two);
回答by Sinan
I would run the second as a callback function:
我会将第二个作为回调函数运行:
$('div#animateTest1').animate({ left: '+=200' }, 2000, function(){
two();
});
which would run two() when first animation finishes, if you have more animations on timed queue for such cases i use jquery timer plugininstead setTimeout(), which comes very handy in some cases.
这将在第一个动画完成时运行 two(),如果在这种情况下定时队列中有更多动画,我使用jquery 计时器插件代替 setTimeout(),这在某些情况下非常方便。
回答by gamadrillen
A safer and 100% working way is to use a variable and if-branches. In the example below we do 4 jobs which take 1 second, after the job we want the function f2 to run.
更安全且 100% 工作的方法是使用变量和 if 分支。在下面的示例中,我们执行 4 个需要 1 秒的作业,在作业之后我们希望函数 f2 运行。
<html><body>
<div id="a" class="a" />
<script type="text/javascript">
var jobs = 0;
function f1() {
job();
job();
job();
job();
};
function f2() {
if(jobs >3)
l("f2");
};
<!------------------------- ->
function job() {
setTimeout(function() {
l("j");
jobs+=1;
f2();
}, 1000);
}
function l(a) {
document.getElementById('a').innerHTML+=a+"<br />";
};
f1();
</script></body></html>
回答by DigitalDesignDj
Really Simple Fix.
非常简单的修复。
function One() {
$('div#animateTest1').animate({ left: '+=200' }, 2000, Two);
}
function Two() {
$('div#animateTest2').animate({ width: '+=200' }, 2000);
}
// Call these functions sequentially so that the animations
// in One() run b/f the animations in Two()
One();
//We no longer need to call Two, as it will be called when 1 is completed.
//Two();
回答by Florin Daniel
$('div#animateTest1').animate({left: '+=200'},2000,
function(){
$('div#animateTest2').animate({ width: '+=200' }, 2000);
}
);
回答by Jacques
Copy and pasting............7/9/2013
复制和粘贴................................7/9/2013
<!doctype html>
<html lang="en">
enter code here<head>
<meta charset="utf-8">
<title>jQuery.queue demo</title>
<style>
div { margin:3px; width:40px; height:40px;
position:absolute; left:0px; top:30px;
background:green; display:none; }
div.newcolor { background:blue; }
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
<button id="start">Start</button>
<button id="stop">Stop</button>
<div></div>
<script>
$("#start").click(function () {
$("div").show("slow");
$("div").animate({left:'+=200'},5000);
jQuery.queue( $("div")[0], "fx", function () {
$(this).addClass("newcolor");
jQuery.dequeue( this );
});
$("div").animate({left:'-=200'},1500);
jQuery.queue( $("div")[0], "fx", function () {
$(this).removeClass("newcolor");
jQuery.dequeue( this );
});
$("div").slideUp();
});
$("#stop").click(function () {
jQuery.queue( $("div")[0], "fx", [] );
$("div").stop();
});
</script>
</body>
</html>