2009-08-10 41 views
7

我試圖在jQuery的慢速操作過程中顯示一個小的加載圖像,但無法正確顯示。 這是一張有數千行的大表格。當我檢查「mostrarArticulosDeReferencia」複選框時,它會從這些行中刪除「隱藏」類。這個操作需要幾秒鐘,我想給出一些反饋。 「加載」是用小gif動畫jQuery在緩慢的操作過程中顯示「加載」

這裏一個div是完整的代碼

jQuery(document).ready(function() { 
jQuery("#mostrarArticulosDeReferencia").click(function(event){ 
    if(jQuery("#mostrarArticulosDeReferencia").attr("checked")) { 
     jQuery("#loading").show(); //not showing 
     jQuery("#listadoArticulos tr.r").removeClass("hidden"); //slow operation 
     jQuery("#loading").hide(); 
    } else { 
     jQuery("#loading").show(); //not showing 
     jQuery("#listadoArticulos tr.r").addClass("hidden"); //slow operation 
     jQuery("#loading").hide(); 
    } 
}); 
jQuery("#loading").hide(); 
}); 

看起來jQuery是「優化」的三線

 jQuery("#loading").show(); //not showing 
     jQuery("#listadoArticulos tr.r").removeClass("hidden"); 
     jQuery("#loading").hide(); 

而且從來沒有顯示加載DIV。 任何想法?

加成:有更快的方式做這種顯示/隱藏的事情?發現切換方式比較慢。

更新: 我想這

jQuery("#mostrarArticulosDeReferencia").click(function(event){ 
    if(jQuery("#mostrarArticulosDeReferencia").attr("checked")) { 
      jQuery("#loading").show(); //not showing 
      jQuery("#listadoArticulos tr.r").removeClass("hidden"); //slow operation 
      setTimeout("jQuery('#loading').hide()", 1000); 
    } else { 
      jQuery("#loading").show(); //not showing 
      jQuery("#listadoArticulos tr.r").addClass("hidden"); //slow operation 
      setTimeout("jQuery('#loading').hide()", 1000); 
    } 
}); 

這就是我得到

  1. 點擊複選框
  2. 沒有在2/3秒(處理)
  3. 網頁被更新
  4. 發生
  5. 加載div在瞬間顯示

更新2: 我有一個工作解決方案。但爲什麼我要使用的setTimeout,使其工作超出了我......

jQuery("#mostrarArticulosDeReferencia").click(function(event){ 
    if(jQuery("#mostrarArticulosDeReferencia").attr("checked")) { 
      jQuery("#loading").show(); 
      setTimeout("jQuery('#listadoArticulos tr.r').removeClass('hidden');", 1); 
      setTimeout("jQuery('#loading').hide()", 1); 
    } else { 
      jQuery("#loading").show(); 
      setTimeout("jQuery('#listadoArticulos tr.r').addClass('hidden');", 1); 
      setTimeout("jQuery('#loading').hide()", 1); 
    } 
}); 

更新3: 剛剛發現的這種特殊情況下更好的解決方案。

//mostrar u ocultar articulos de referencia 
$("#mostrarArticulosDeReferencia").click(function(event){ 
    if($("#mostrarArticulosDeReferencia").attr("checked")) 
     $("tr.r").css({'display':'table-row'}); 
    else 
     $("tr.r").css({'display':'none'}); 
}); 

使用的.css({「顯示」:「無」})原來是WAY不是隱藏()快,因此無需加載動畫...
這篇文章給我看光:show/hide performance

+0

你想在加載頁面時運行它嗎? $(document).ready()在所有內容都被關閉並加載時觸發 – AutomatedTester 2009-08-10 06:42:59

+0

不需要,我只在顯示/隱藏操作期間需要這個。 剛剛粘貼了整個腳本 – 2009-08-10 06:46:05

+1

只是一個想法,你有嘗試過使用上下文嗎?如果您在選擇器語句中提供第二個參數,這可以幫助加速。 – 2009-08-10 08:21:23

回答

2

我試了一切,我不得不得出結論,這是瀏覽器brainfart的產品。

  1. 的jQuery告訴瀏覽器顯示/隱藏加載DIV
  2. 的jQuery告訴瀏覽器添加從行
  3. 的jQuery告訴瀏覽器/刪除隱藏類顯示/隱藏加載DIV
  4. 瀏覽器就以錯誤的順序(2排在首位)所有上述步驟

「setTimeout的」在我的最後一次更新是迫使瀏覽器執行壽按照正確的順序中的所有步驟。 它吮吸,不是優雅,但至少它的作品...

更新:setTimeout是必要的,因爲jquery「簡化」的命令鏈。如果我告訴它隱藏一個元素並再次顯示它,它將簡單地忽略該命令,因爲最終結果將與無所作爲相同。

+0

我想我添加了一條評論,說這個答案誤導了正確的答案,並且沒有來自瀏覽器部分的brainfart,它來自jquery庫,並且它對removeClass回調沒有回調(它看起來像自然)。我不知道爲什麼它被刪除。 – 2013-02-04 07:50:34

0

您是否試過使用ajaxStart來運行您的更新功能?

+0

你會如何使用它?無法得到它的工作 – 2009-08-10 07:22:31

+0

檢查此問題:http://stackoverflow.com/questions/1191485/how-to-call-ajaxstart-on-specific-ajax-calls – Jason 2009-08-10 07:28:17

0

我認爲它工作正常。此操作:

jQuery("#listadoArticulos tr.r").removeClass("hidden"); 

是不是真的那麼慢,它在幾毫秒頂部進行,所以你看不到的加載信息,因爲它只是在那裏很短的時間。

+0

我有幾行,它需要2或3秒。這是非常討厭的 – 2009-08-10 06:50:39

+0

如果你註釋掉隱藏和刪除類指令,你會看到加載div嗎? – RaYell 2009-08-10 07:21:18

+0

就像你說的那樣? \t的jQuery( 「#mostrarArticulosDeReferencia」)。點擊(函數(事件){ \t \t如果(jQuery的( 「#mostrarArticulosDeReferencia」)。ATTR( 「選中」)){ \t \t \t \t的jQuery( 「#加載」 ).show(); //未示出 \t \t \t \t // jQuery的( 「#listadoArticulos tr.r」)removeClass( 「隱藏」); //慢的操作 \t \t \t \t // jQuery的(「#加載「)。hide(); \t \t} else { \t \t \t \t jQuery(「#loading」)。show(); //不顯示 \t \t \t \t // jQuery(「#listadoArticulul tr.r」)。addClass(「hidden」); //運行緩慢 \t \t \t \t // jQuery(「#loading」)。hide(); \t \t} \t}); 是的,我看到加載div,但我後來隱藏它的書呆子... – 2009-08-10 07:29:36

1

我想你想要做

jQuery("#listadoArticulos tr.r").removeClass("hidden"); 

作秀的回調函數內。

看看這個方法的文檔在這裏:http://docs.jquery.com/Effects/show

可以實現通過調用show(0);

相同的「即時顯示」效果,但是你想做的回調?沒問題,這樣做:

show(0, function() { jQuery("#listadoArticulos tr.r").removeClass("hidden"); }); 

簡單! :)

+0

這樣做我得到了和以前一樣的行爲 1.點擊複選框 2.在2/3秒內沒有任何反應(處理) 3。頁面得到更新 4.加載div在分秒顯示 而且我必須使用settimeout來隱藏div。如果我不使用它,該div永遠不會顯示... – 2009-08-10 08:57:21

+0

你有沒有一個我可以玩的現場例子?我在考慮改變每一行,如果你有一整套,你可以改變tbody標籤。 – 2009-08-10 09:48:08

0

我也看到了這種行爲,這取決於使用的瀏覽器。 IE是受影響最大的一個。原因不是jQuery很慢,儘管JavaScript在IE中運行速度較慢,但​​更多的是由於新HTML的呈現。 setTimeout()幫助的原因是因爲它執行了第一個操作,並且只有在瀏覽器完成呈現新的HTML時才完成第二部分。整個操作實際上比較慢,但反饋使它更好。

演示這一點的一種方法是隱藏長表並運行相同的代碼。它會做同樣的事情,但由於表格是隱形的,並且不會使整個動作更快。

有幾種方法可以解決這個問題。

  1. 儘量避免使用表格並改爲使用DIV佈局。表格渲染速度慢,並且根據瀏覽器的不同,表格可能只能被看到然後完全渲染。
  2. 如果您必須使用表格,請考慮使用多個粘貼在一起的100行表格。這樣一旦第一張表格被重新格式化,頁面就開始渲染。
  3. 如果只有一個大表是唯一的出路,而且您知道用戶只能看到頂部的行,您可以兩次執行操作,第一次在頂部行中,第二次在所有行上執行。這是最慢和最不理想的解決方案,但可以通過向操作添加jQuery篩選器來實現,非常容易。
+1

你爲什麼推薦表格數據的div?你爲什麼建議分解數據?你關心語義嗎? – 2009-08-10 08:25:57

+1

或可訪問性? – 2009-08-10 08:26:33

+0

主要是因爲瀏覽器中表格的渲染速度。使用div和css是一個很好的選擇。當然,也可以選擇使用固定的桌面佈局,這也會有所幫助。請參閱:http://stackoverflow.com/questions/1046035/why-is-ie7-so-slow-compared-to-safari。 – Maurice 2009-08-10 08:35:06

0

這不回答原來的問題,但它是任何更快地對錶本身使用CSS規則的一類:

#listadoArticulos.hideCertainRows tr.r { display: none } 

和切換這樣的顯示:

jQuery("#listadoArticulos").addClass("hideCertainRows"); 

3

顯然你在燒製過程中的「長時間運行進程」的異步請求(是的,異步,換句話說,它不與代碼同步運行!)。您需要在異步請求的回調函數結束時調用$('#loading').hide()

這裏是一個很好的例子:

$('#loading').show(); 
$.getJSON('someURL', function(data) { 
    // Do slow processing. 
}); 
$('#loading').hide(); 

這顯然是行不通的。它會顯示,觸發一個異步請求,然後立即隱藏。你需要重寫代碼:

$('#loading').show(); 
$.getJSON('someURL', function(data) { 
    // Do slow processing. 
    $('#loading').hide(); 
}); 
+0

有時很簡單的事情就是答案。感謝BalusC的例子。 – Chris 2013-12-03 19:03:37

1

剛一說明 - 我已經開發了plugin創建與它裝載圖形疊加股利。

1

把一個div您的網頁上的某個地方,像這樣:

<div id="spinner" class="spinner" style="display:none;"> 
    <img id="img-spinner" src="@Url.Content("~/images/loading.gif")" alt="Loading"/> 
</div> 

然後勾顯示和隱藏於ajaxStart,ajaxStop和ajaxError事件,像這樣:

$("#spinner").bind("ajaxSend", function() { $(this).show(); }) 
$("#spinner").bind("ajaxStop", function() { $(this).hide(); }) 
$("#spinner").bind("ajaxError", function() { $(this).hide(); }); 
0

嘗試使用回調「完整」的展示方法,js大部分基於異步事件,並且這三行:

jQuery("#loading").show(); //not showing 
jQuery("#listadoArticulos tr.r").removeClass("hidden"); 
jQuery("#loading").hide(); 

是g無需等待即可執行,因此,您的演出,添加課程並立即隱藏div,這就是爲什麼您無法看到div的原因,您無需等待即可隱藏它,並且它看起來很快,甚至消失得非常快,甚至它可能永遠不會顯示(不知道該類型的任何優化)。

如果在完整的回調中添加最後兩個,它將起作用,更多http://api.jquery。COM /顯示/:

jQuery("#loading").show(400, function(){ 
    jQuery("#listadoArticulos tr.r").removeClass("hidden"); 
    jQuery("#loading").hide(); 
}); 

在任何情況下,也在爲Ajax請求,這樣做的正確方法(我想象將是有用的人)使用ajaxStartajaxStop這樣的:

$(document).ajaxStart(function() { 
    $("#loading").show(); 
}).ajaxStop(function() { 
    $("#loading").hide(); 
}); 

加入了removeClass沒有回調的:

也許你的問題躺在事實,那就是對於removeClass沒有回調,但你可以做下一個:

jQuery("#loading").show(400, function(){ 
    var els = jQuery("#listadoArticulos tr.r"); 
    els.each(function(i, el) { 
     el.removeClass("hidden"); 
     if (els.length == i +1) jQuery("#loading").hide(); 
    }); 
}); 

試試這個太:

var els = jQuery("#listadoArticulos tr.r"); 
els.each(function(i, el) { 
    if (i == 0) jQuery("#loading").show(); 
    el.removeClass("hidden"); 
    if (els.length == i +1) jQuery("#loading").hide(); 
}); 

您可以添加這個問題,如果你有圖片或激活,一旦你刪除類的任何額外的代碼,就恨不得躲裝載沒有本機方法div,所以即使你刪除隱藏的類,也沒有簡單的方法來等待對象可見。

我只是注意到,這是2年前,也許你不需要這個了。