3

各キーダウン イベントで以下のコードを実行するテキスト フィールドがあるとします。

if( $('#my_input').val() == '' )
  $('#my_span').html('my input is blank');
else
  $('#my_span').html('My input is not blank');

明らかに、何か (要素) の状態を既存の状態に設定する可能性のあるコードを実行し#my_spanていますが、これは非効率的です。しかし、私は代替手段が何であるかについて興味がありますか? 次のようなチェックを追加します。

if ( $('#my_input').val() == '' ){
  if ( $('#my_span').html() != 'my input is blank' )
       $('#my_span').html('my input is blank');
}
else if ( $('#my_span').html() != 'My input is not blank' )
          $('#myspan').html('My input is not blank');

後者はより効率的ですか?私にはもっと「正しい」ように思えますが、明らかにコードが多く、最初の例よりもどれだけ効率的かはわかりません。

前者には常にDOM操作が含まれ、相対的な効率の計算に影響することは知っていますが、以前にDOMに関連しないコードでこのような状況に遭遇したことがあるので、すべての場合に最適なアプローチは何ですか. 何かの値を新しい値に設定する前に、その値を常に追加チェックする必要がありますか?

編集:

私の最終バージョンでは、実際にここでの回答を組み合わせて使用​​しているため、すばらしい回答をありがとうございます。要約すると、私は今:

  • jquery オブジェクトをクロージャーにキャッシュする
  • 状態を使用して、新しい状態への割り当てを決定します

また余談ですが、キーダウンの setTimeout は、入力フィールドの値をすぐに取得するための非常に優れた方法です。再度、感謝します。

4

7 に答える 7

7

jQueryオブジェクトをキャッシュし、ブール値を使用して状態を保存し、html必要がない場合は呼び出しません。

(function(){
   var i = $('#my_input'), s=$('#my_span'), blank, check = function() {
      if (i.val()=='') {
         if (blank!==true) s.html('my input is blank');
         blank = true;
      } else {
         if (blank!==false) s.html('my input is not blank');
         blank = false;
      }
   };
   i.keyup(check);
   check(); // so that the span is initially filled
})();

keydown必要なのはbutではないことに注意してくださいkeyup。そのため、イベントを取得する前に入力の値が変更されます。

于 2013-06-04T17:19:12.993 に答える
4

これは私が思いつくことができる最も速くて素晴らしいです:

function keyUpEvent(){
    var state = null,
        input = $('#my_input'),
        span = $('#my_span');

    return function(){
        var test = input.val() === '';
        if( test === state) return;
        if(test)
          span.html('my input is blank');
        else
          span.html('My input is not blank');
        state = test;
    }
}
$('#my_input').keyup(keyUpEvent());

http://jsfiddle.net/TMb8T/

これはクロージャを使用して、初期化後に入力要素とスパン要素を格納します。そして、それを(ほとんど)通常の機能のように使用できるため、複数のイベントをバインドして、引き続き機能します。keyUpEventイベントをバインドするときに実行する必要があることに注意してください。

追加: 次のようなこともできるようになりました:

function keyUpEvent(input, span){
    var state = null;

    return function(){
        var test = input.val() === '';
        if( test === state) return;
        if(test)
            span.html('My input is blank');
        else
            span.html('My input is not blank');
        state = test;
    }
}


$('#my_input').keyup( keyUpEvent($('#my_input'), $('#my_span')) );
$('#my_input2').keyup( keyUpEvent($('#my_input2'), $('#my_span2')) );

http://jsfiddle.net/TMb8T/2/

このように、フォーム全体のすべての入力を 1 つのイベント ハンドラで簡単にチェックできます。

追加2:キーが押されたままでもバージョン2を動作させたい場合;)

これを置き換えます:

$('#my_input').keyup( keyUpEvent($('#my_input'), $('#my_span')) );

これとともに:

$('#my_input').keydown(function(){
    setTimeout(keyUpEvent($('#my_input'), $('#my_span')),1);
});

http://jsfiddle.net/TMb8T/4/

于 2013-06-04T17:37:17.747 に答える
3

コードを実行する頻度に大きく依存します。ユーザーがボタンなどを押したときにのみ実行される場合は、最初のものを使用しても問題ありません。クイックタイマーで実行すると、そうでない場合があります。

次のようにします。

var text;
if ( $('#my_input').val() == '' )
    text = 'my input is blank';
else 
    text = 'My input is not blank';

if ( $(#my_span).html() != text )
    $('#my_span').html(text);
于 2013-06-04T17:19:58.883 に答える
1

あなたは三項でそれを単純化することができます

$('#my_span').html( $('#my_input').val() == '' ? 'my input is blank' : 'My input is not blank' );

より読みやすく

var text = $('#my_input').val() == '' ? 'my input is blank' : 'My input is not blank';
$('#my_span').html(text);

そして、速度を気にするなら、DOM の再描画はコンテンツの読み取りよりも高速です。それは本当にページ構造/サイズ、ブラウザに依存します. JSPerf は、何千回もの反復で何ミリ秒節約できるかを知りたい場合に役立ちます。パフォーマンスの問題が発生した場合は、本当に最速のものを探す必要があります。

  1. チェックなし、書き込み内容
    • データが変更された場合、または変更されなかった場合、DOM を更新するというペナルティがあります。
  2. チェック、書き込み内容
    • HTMLを読むというペナルティがあります
    • DOM を更新するとペナルティがあります
  3. チェック、書き込み不要
    • HTMLを読むというペナルティがあります

では、HTML は異なるものになる可能性が最も高いのでしょうか?

解決策は、何をしたいかによって異なります。jQuery 要素をキャッシュすると、検索/書き込みが高速化されます。単なる書き込みよりも遅くなります。

于 2013-06-04T17:17:44.043 に答える
1

初期化:

var isBlank = true;

$('#my_span').html('my input is blank');

キーアップ:

if(!isBlank){
    if( $('#my_input').val().length == 0){
        isBlank = true;
        $('#my_span').html('my input is blank');
    }
} else {
    if($('#my_input').val().length){
        isBlank = false;
        $('#my_span').html('my input is not blank');
    }
}

このようにして、状態が変化した場合にのみ DOM を操作します。

また、インタープリターが文字列リテラルから文字列オブジェクトを作成する必要がないため、"" に対して文字列をテストするよりも、長さプロパティをテストする方が実際には高速である可能性があります。

于 2013-06-04T17:23:23.820 に答える
-1

現在の値を変数に保存し、変数をテストして変更する必要があるかどうかを確認するのはどうですか。変更が必要になるまで、DOM をいじる必要はありません。(ここで良い効果を得るために名前付きブール値を使用することもできisBlankます):

var currValue;
if ( $('#my_input').val() == '' ) {
  if ( currValue != 'my input is blank' ) {
       currValue = 'my input is blank';
       $('#my_span').html(currValue);
  }
} else if ( currValue != 'My input is not blank' ) {
       currValue = 'My input is not blank';
       $('#my_span').html(currValue);
}

また、これは keydown イベントハンドラーにあると述べました。

  1. このコードを最初に 1 回実行することを忘れないでください。これにより、最初は入力フィールドが空白であることを示すように表示フィールドが設定されます。
  2. ユーザーはテキストを選択し、右クリックして「切り取り」を選択してフィールドを空にするか、「貼り付け」を選択してテキストをフィールドに追加できることを忘れないでください。同様に、ドラッグ アンド ドロップ操作で、テキストを追加または削除できると考えられます。

思考の代替列車

チェックする定期的な時限イベントを使用する方がよい場合があります。1 秒間に 3 ~ 4 回キーを連続して入力できる人もいます。1 秒ごとにフィールドを確認するように時間を設定すると、このコードの実行による短期的なスローダウンを削減し、CPU サイクルの長期的な一定の使用に置き換えることができます。ただし、コンピュータが興味深いことをしていない場合、CPU サイクルを使用しない理由はないことを覚えておいてください。

于 2013-06-04T17:17:20.087 に答える