iT邦幫忙

6

jQuery queue 用法

試著介紹複雜的 $(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


尚未有邦友留言

立即登入留言