2010-10-20 113 views
5

我最近開始使用jQuery,今天發現了一個奇怪的問題,它是如何爲我表現的。據我所知,JavaScript是單線程的。所以它的所有操作都應該以FIFO爲基礎運行。但是,這似乎並不適合我。請考慮以下事項。jQuery沒有以正確的順序執行?

SETUP是如下

HTML:

3的div

  • DIV#1 =>包含可點擊來執行排序功能

  • 首標元素

    div#2 =>包含需要排序的數據

  • DIV#3 =>包含用於通知正在執行

jQuery的 一些操作的用戶的基本.gif要點 - 包含排序函數確實DOM操作。基本上,它從HTML頁面讀取數據,存儲在二維數組中,並對數組進行排序。然後它完全清除div#2(data div),並使用來自排序數組的數據重建它。

EXECUTION預計是如下

  • 用戶點擊標題之一來觸發排序功能
  • 排序函數隱藏DIV#2和示出DIV#3
  • 排序功能是執行
  • 一旦排序完成,div#2(data div)被顯示,div#3被隱藏

然而,這裏是什麼似乎發生

  • 用戶點擊標題

  • 排序發生

  • 隱藏和申報單的表現發生在最後一步

最初,由於我無法看到任何div顯示/隱藏,我假設它發生得太快,我不能注意到。所以我給jQuery的.show()和.hide()函數添加了時間延遲。一旦完成,很明顯,展示和隱藏行動正在結束。

*解* 一番搜索後,我好不容易如我所料通過使用jQuery .queue()和.dequeue()函數來得到這個工作。這裏的致命弱點是我必須在每次操作之間插入1毫秒的延遲。然後,只有這樣,瀏覽器才能夠按照我的意願隱藏/顯示div。因此,操作又是這樣的:

var theQueue = $({}); // jQuery on an empty object 

theQueue.queue("testQueue", 
       function(next) { 
        $("#loadingIndicator").show(); 
        $("#cases").hide(); 
        next(); 
       } 
      ); 
theQueue.delay(1, "testQueue"); 

theQueue.queue("testQueue", 
       function(next) { 
        doSort(columnNumber); //SORT 
        next(); 
       } 
      ); 
theQueue.delay(1, "testQueue"); 

theQueue.queue("testQueue", 
       function(next) { 
        $("#loadingIndicator").hide(); 
        $("#cases").show(); 
        next(); 
       } 
      ); 

theQueue.dequeue("testQueue"); 

}

我肯定不會對此事的專家,但我認爲操作應該以相同的順序執行,因爲他們被稱爲。瀏覽器沒有按照正確的順序渲染? jQuery是否改變操作的順序以使事情更有效率?

儘管「解決方案」完成了這項工作,但我並不認爲這是這種情況下的最佳解決方案。有沒有其他方法可以做到這一點?如果需要,我可以提供能夠證明問題的工作代碼示例。謝謝。

另一方面,我注意到大數據集,當用戶點擊一個頭元素來觸發排序時,瀏覽器變得沒有反應。我意識到它正在執行排序功能,但我希望有一種方法可以避免這種情況。有什麼想法嗎?

回答

7

這些操作的執行順序與它們被調用的順序相同,但問題在於DOM元素和屏幕上顯示的內容是兩個單獨的東西。將元素呈現在屏幕上的過程與Javascript代碼在同一單線程環境中運行,因此在腳本完成之前它不能在sceen上顯示任何更改。

要讓更改顯示出來,您必須結束腳本,然後在渲染器有機會顯示更改時恢復它。

可以使用setTimeout方法來控制返回給瀏覽器,並獲得代碼的其餘部分儘快啓動:

$("#loadingIndicator").show(); 
$("#cases").hide(); 

window.setTimeout(function(){ 

    doSort(columnNumber); //SORT 
    $("#loadingIndicator").hide(); 
    $("#cases").show(); 

}, 0); 
+0

太棒了,謝謝你的易於解釋。我現在正在使用這種方法,我必須說它使用的代碼少於我使用的其他隊列方法。乾杯。 – Harinder 2010-10-21 14:09:50

1

.show().hide()是FX隊列,這是成員不會中止程序執行,而是異步執行。

效果可能會通過鏈接按順序排隊,但其他代碼將獨立於fx隊列執行而執行。以您想要的方式獲取操作順序的方法是像您一樣創建自定義隊列,或者爲每個效果使用回調函數。

E.g.

$('#loadingIndicator').show(250,function(){ 
    $('#cases').hide(250,function(){ 
     doSort(columnNumber); 
    }).show(250, function(){ 
     $('#loadingIndicator').hide(250);}) 
}); 

JSFiddle example

ED:我不小心整個單詞。

+0

謝謝你的洞察力。我相信這個自定義隊列信息將在不久的將來派上用場。 – Harinder 2010-10-21 14:11:33