My flickr

我的
我的
我的

views: 997 times
前陣子例用 queue 做了許多東西,慢慢的發現,原生的 stop() 並非我想像中的樣子。
  1. 使用任何的動態效果,或是 delay() 這樣的效果,stop() 能使之停止。
  2. 使用 queue(),stop() 能使之停止。
  3. stop() 可以傳入兩個布林值,一個是 clearQueue,另一個是 JumpToEnd。
然而,我卻發現事實上並不是這樣。
  1. stop() 僅可停止單一動態動態效果,若連續使用並不會停止後續動作。
    例如:$('div').animate( { 'left' : '500px' } ).delay(1000).animate( { 'left' : '0px' } );
    使用 stop() 僅會停止紅色的區域,綠色區域會繼續執行,很不幸的,他不會停止!

  2. clearQueue:true 會清除所有關於動態效果的執行動作。
    例如:$('div').animate( { 'left' : '500px' } ).delay(1000).animate( { 'left' : '0px' } );
    使用 stop(true) 停止所有動作,且會停在執行中的結果。但是如果你再次呼叫時,他會從頭開始執行

    問題來了,如果我在 .animate( { 'left' : '500px' } ) 之後才按下 stop(true),然後再次呼叫時,因為會從頭開始執行的關係,所以 .animate( { 'left' : '500px' } ) 會再執行一次,這是動態效果中不想見到的,因為看起來會像是沒有在動作一樣(因為已經做完了)。

    另外,倘若我在 .animate( { 'left' : '0px' } ) 之後按下 stop(true),然後再次呼叫時,因為從頭開始執行的關係,他會重複上一次的動作,這也是效果中不想見到的,因為應該是繼續最後一個步驟。

  3. JumpToEnd:true 會直接結束該段動態效果,並繼續往下執行。
    例如:$('div').animate( { 'left' : '500px' } ).delay(1000).animate( { 'left' : '0px' } );
    使用 stop(false,true) 直接顯示紅色區域的結果,然後綠色區域會繼續執行,很不幸的,他依舊不會停止!

  4. clearQueue:true, JumpToEnd:true 清除所有關於動態效果的執行動作,並結束該段動態效果。
    例如:$('div').animate( { 'left' : '500px' } ).delay(1000).animate( { 'left' : '0px' } );
    使用 stop(false,true) 直接顯示紅色區域 的結果,綠色區域會停止執行。但是如果你再次呼叫時, 他會從頭開始執行。問題跟第 2 點一樣,若再次呼叫時,他會從頭開始執行

  5. jQuery 1.4 之後新增了 .clearQuere(),雖然方便,但是跟 stop() 的問題是一樣的。
接著,我來說一下我所預期的 stop() 是怎麼樣的一個情況:
  1. stop() 應該停止整段動態效果,所以他應該是 clearQueue:true, JumpToEnd:true 的狀態,至於動態執行的階段問題,應該由動態撰寫者自行決定是否重設。

  2. clearQueue:true 應該更謹慎使用!由於會重設整段動態效果,所以執行階段問題一樣是要由撰寫者自行決定是否該重新設定

  3. JumpToEnd:true 完全誤導使用者對於 stop() 的概念與本身詞意!也許這是很嚴重的指責,但是我不得不這麼說,當你的動作在被按下 stop() 之後,卻被使用者發現還會執行後續動作,這不是很詭譎嗎!

  4. clearQueue:true, JumpToEnd:true 應該是預設值,而 stop() 應該被修改甚至消滅!

  5. .clearQueue() 並沒有好到哪去。
所以,我們來看看 jQuery 關於 stop() 的核心做了甚麼事情:

stop: function( clearQueue, gotoEnd ) {
        var timers = jQuery.timers;

        /// 剛剛說的,clearQueue: true 時會將整個 queue 清空
        if ( clearQueue ) {
            this.queue([]);
        }

        this.each(function() {
            // go in reverse order so anything added to the queue during the loop is ignored
            for ( var i = timers.length - 1; i >= 0; i-- ) {
                if ( timers[i].elem === this ) {

                    /// 當 JumpToEnd:true 時,會直接結束該段 animate 的 setTimeout
                    if (gotoEnd) {
                        // force the next step to be the last
                        timers[i](true);
                    }

                    timers.splice(i, 1);
                }
            }
        });

        // start the next in the queue if the last step wasn't forced

        /// 誰能告訴我,為什麼 JumpToEnd:false (預設值) 的時候,要執行下一個 queue 內容?
        /// 所以我才說,stop() 這個指令的預設值,完全違背了本身的概念與詞意!

        if ( !gotoEnd ) {
            this.dequeue();
        }

        return this;
    }

現在知道問題點了嗎?這個 stop() 的預設值所表現的行為,應該叫做 StopAndPlay() 才對!
創用 CC 授權
Creative Commons License
本創作適用 姓名標示-非商業性-禁止改作3.0 創用 CC 授權,台灣並依循所適用的授權條款。
 相關文章 

Writer profile
author image
偏執與強迫症的患者,算不上是無可救藥,只是我已經遇上我的良醫了。

Posted by hina

2010/02/27 00:10 2010/02/27 00:10
, , , , , , , ,
Response
No Trackback , No Comment
RSS :
http://blog.hinablue.me/rss/response/827

Trackback URL : http://blog.hinablue.me/trackback/827

« Previous : 1 : ... 37 : 38 : 39 : 40 : 41 : 42 : 43 : 44 : 45 : ... 828 : Next »