8

jQuery での遅い操作中に小さな読み込みイメージを表示しようとしていますが、正しく表示されません。これは、数千行の BIG テーブルです。「mostrarArticulosDeReferencia」チェックボックスをオンにすると、これらの行から「非表示」クラスが削除されます。この操作には数秒かかります。フィードバックをお願いします。「loading」は、小さなアニメーション gif を含む 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がこれらの3行を「最適化」しているようです

        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. 読み込み中の 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({'display':'none'}) を使用すると、 hide () よりもはるかに高速であることが判明したため、ローディング アニメーションは必要あり
ません。

4

10 に答える 10

3

私はすべてを試しましたが、これはブラウザの頭脳の産物であると結論付けなければなりません.

  1. jQueryはブラウザに読み込み中のdivを表示/非表示にするように指示します
  2. jQuery はブラウザに行から非表示のクラスを追加/削除するように指示します
  3. jQueryはブラウザに読み込み中のdivを表示/非表示にするように指示します
  4. ブラウザは上記のすべての手順を間違った順序で実行します (最初に 2 つ)

私の最後の更新の「setTimeout」は、ブラウザにすべてのステップを正しい順序で強制的に実行させています。それは最悪で、エレガントではありませんが、少なくとも機能します...

更新: jquery は一連のコマンドを「簡素化」するため、setTimeout が必要です。ある要素を非表示にして再度表示するように指示すると、最終結果は何もしないのと同じになるため、単にコマンドを無視します...

于 2009-09-20T03:50:57.007 に答える
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();
});
于 2010-03-17T17:35:43.837 に答える
1

次のように、ページのどこかに div を配置します。

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

次に、次のように、show と hide を ajaxStart、ajaxStop、および ajaxError イベントにフックします。

$("#spinner").bind("ajaxSend", function() { $(this).show(); })
$("#spinner").bind("ajaxStop", function() { $(this).hide(); })
$("#spinner").bind("ajaxError", function() { $(this).hide(); });
于 2012-03-13T22:05:04.690 に答える
1

やりたいと思う

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

show のコールバック関数内。

ここでメソッドのドキュメントを見てください: http://docs.jquery.com/Effects/show

を呼び出すことで、同じ「即時表示」効果を実現できます。show(0);

しかし、あなたはコールバックをしたいですか? 問題ありません。次のようにします。

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

単純!:)

于 2009-08-10T08:23:01.760 に答える
1

注意点 -ロード中のグラフィックを含むオーバーレイ div を作成するためのプラグインを開発しました。

于 2010-07-18T16:05:52.940 に答える
0

ajaxStartを使用して更新機能を実行してみましたか?

于 2009-08-10T06:45:48.460 に答える
0

正しく動作していると思います。この操作:

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

それほど遅くはなく、数ミリ秒のトップで実行されるため、ロード情報は非常に短い時間しか表示されないため、表示されません。

于 2009-08-10T06:47:38.253 に答える
0

私もこの動作を確認しましたが、使用するブラウザによって異なります。IE が最も影響を受けます。その理由は、IE では JavaScript の実行が遅くても、jQuery が遅いからではなく、新しい HTML のレンダリングが原因です。setTimeout() が役立つ理由は、それが最初のアクションを実行し、ブラウザーが新しい HTML のレンダリングを完了したときにのみ 2 番目の部分が実行されるためです。全体の操作は実際には遅くなりますが、フィードバックにより改善されます。

これを実証する 1 つの方法は、長いテーブルを非表示にして同じコードを実行することです。同じことを行いますが、テーブルが見えず、アクション全体がレンダリングされないため、はるかに高速になります。

これを回避するには、いくつかの方法があります。

  1. テーブルを避けて、代わりに DIV レイアウトを使用してください。テーブルのレンダリングが遅く、ブラウザーによっては、テーブルが表示されてから完全にレンダリングされる場合があります。
  2. テーブルを使用する必要がある場合は、たとえば 100 行をまとめて複数のテーブルを使用することを検討してください。そうすれば、最初のテーブルが再フォーマットされるとすぐにページのレンダリングが開始されます。
  3. 1 つの大きなテーブルが唯一の方法であり、ユーザーが一番上の行しか見ることができないことがわかっている場合は、1 回目は一番上の行で、2 回目はすべての行で、2 回アクションを実行できます。これは最も遅く最適でないソリューションですが、jQuery フィルターをアクションに追加することで非常に簡単に実装できます。
于 2009-08-10T08:23:10.417 に答える
0

これは元の質問には答えませんが、テーブル自体のクラスに CSS ルールを使用する方が高速ですか?

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

次のように表示を切り替えます。

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

?

于 2010-03-17T17:28:03.733 に答える
0

show メソッドのコールバック「complete」を使用してみてください。js はほとんどが非同期イベントに基づいており、次の 3 行です。

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

待機せずに実行されるため、表示、クラスの追加、div の非表示をすぐに実行すると、div が表示されないため、表示されるのを待たずに非表示にすると、非常に速く表示および非表示になります。表示されない場合もあります(そのタイプの最適化については知りません)。

完全なコールバック内に最後の 2 つを追加すると、機能します。さらに http://api.jquery.com/show/:

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 年前のことですが、もう必要ないかもしれません。

于 2013-02-02T03:49:38.600 に答える