试着介绍複杂的 $(selector).queue() 的用法
所谓的 queue ,主要是把多个「非同步」的 task 「依序」做完。
(不是说同步不行,只是同步的话不需要靠 queue 就会依序做完,
不需要特别做 queue 。)
在 jQuery 状况下,queue 主要是拿来作 animation 效果内部实作,
反而不多人会在正式开发用它,一方面是他难懂,
另一方面是使用者还不知道什么时候该用 queue。
举个例子,以 fadeIn 来讲,他是将物件显示为显示,并设 opacity 从 0 到 100。
如果我要自己刻一个简易实作,直觉你可能想到要这样作。
http://jsfiddle.net/eqAdS/
<div id="target" style="width:150px;height:150px;background:red;"> Test</div><script> var item = $("#target"); item.show(); item.css("opacity",0); for(var i = 0 ; i < 100 ;++ i){ item.css("opacity", i / 100 ); } item.html("fadeIn invoked");</script>
但是你会发现看不见效果,因为 animation 需要有间隔时间,
看起来才像 animation,不然直接从 0 跑个迴圈到100 ,
时间太短会看不到画面呈现。
那我们下一版改为这样的实作
http://jsfiddle.net/eqAdS/1/
<div id="target" style="width:150px;height:150px;background:red;"> Test</div><script> var item = $("#target") , time = 500; item.show(); item.css("opacity",0); for(var i = 0 ; i <= 100 ; i +=10){ (function(ind){ //use ind to protect variable "i",or it will always be 100 $("#target").queue("fadeIn",function(){ //put all the process into queue item.css("opacity", ind/100 ); setTimeout(function(){ //run next item $("#target").dequeue("fadeIn"); },time); //every 500 ms }); })(i); } $("#target").dequeue("fadeIn"); //start to run items! item.html("fadeIn invoked");</script>
你会发现这次看起来像样多了,他的原理是假设你有十件事情要做,
你可以先用 $(selector).queue(name,function) 推入指定的 queue ,
但是因为我们知道处理流程通常都是非同步的 (timeout / ajax ...etc ),
那系统怎么会知道什么时后要执行下一个呢? 答案是:它就是不知道。
所以你必须要自己告诉他,当你呼叫 $(selector).dequeue(name) 表示说,
我要开始了或我这一轮作完了,作下一轮吧!
比方说偶尔会有个需求是,我希望先做完 ajax1 确定他做完了再作 ajax2 ,
那就会像是以下的 code
//建立第一个排程,此时还没执行$("#target").queue("myqueue",function(){ //do something , like ajax $.post("myurl.php",function(){ //run next queue item after ajax success $("#target").dequeue("myqueue"); }); });//建立第二个排程,此时还没执行$("#target").queue("myqueue",function(){ //do something , like ajax $.post("myurl2.php",function(){ //run next queue item after ajax success $("#target").dequeue("myqueue"); }); });$("#target").dequeue("myqueue");//开始执行//此时它会开始先跑 myurl.php 的 ajax ,确定 success 有收到回应后,//再跑 myurl2.php 的ajax。
当然他还有一些延伸用法,但这里基于教学立场我们就只提到最基本该有的东西:
另外,如果因为某些因素你想清空正在执行的 queue ,像是jQuery animation 的 stop() ,
你可以 call $(selector).clearQueue("myqueue");
附带一提,jQuery 1.4 以后提供更方便的操作方式,
原本写成
$("#target").queue("myqueue",function(){ //do something , like ajax $.post("myurl.php",function(){ //run next queue item after ajax success $("#target").dequeue("myqueue"); }); });
可以改写成
$("#target").queue("myqueue",function(next){ //内建传入 next 方便作dequeue //do something , like ajax $.post("myurl.php",function(){ //run next queue item after ajax success next(); //用传进来的 next function 取代 dequeue() }); });
所以我们最一开始的 myFadeIn 开发範例就可以变成这样,
写起来可以省下不少力气。
http://jsfiddle.net/eqAdS/2/
<div id="target" style="width:150px;height:150px;background:red;"> Test</div><script> var item = $("#target") , time = 500; item.show(); item.css("opacity",0); for(var i = 0 ; i <= 100 ; i +=10){ (function(ind){ //use ind to protect variable "i",or it will always be 100 $("#target").queue("fadeIn",function(next){ //put all the process into queue item.css("opacity", ind/100 ); setTimeout(next,time); //every 500 ms }); })(i); } $("#target").dequeue("fadeIn"); //start to run items! item.html("fadeIn invoked");</script>
Queue 的主要适用情境是:
1.大量同时运算导致网页卡住时,用来作为运算的分流用。
2.操作有相依性,需要等待时(需确定 A 操作完的结果、状态才能操作B ...etc )
3.animation