2016-03-21 7 views
1

私は自分のサイトのインスタント検索をドロップダウンしようとしています。これ以外はすべて正常に動作します。インスタント検索でのajaxコールの数を減らす

var timeOut; 
$('#search input[name=\'search\']').on('keyup', function(e) { 
    // If enter - submit the search field 
    if (e.keyCode == 13) { 
     $('header input[name=\'search\']').parent().find('button').trigger('click'); 
    } 
    // Call only when length is at least 2 and the key pressed is alphanumeric 
    else if ($('#search input[name=\'search\']').val().length>2 && ((e.keyCode>=65 && e.keyCode<=90) || (e.keyCode>=97 && e.keyCode<=122))) { 
     timeOut = null; 
     //alert(timeOut); 

     if (!timeOut) { 
      timeOut = setTimeout(function() { 
       $.ajax({ 
        url: 'ajax.php', 
        type: 'post', 
        async: false, 
        data: 'ACTION=SEARCH&search='+$('#search input[name=\'search\']').val(), 
        dataType: 'json', 
        beforeSend: function() { 
         $('#loader-icon').show(); 
        }, 
        complete: function() { 
         $('#loader-icon').hide(); 
        }, 
        success: function(json) { 
         //$('.product-list-row').html(json); 
         $('#search-listing').html(json['html']); 
        }, 
        error: function(xhr, ajaxOptions, thrownError) { 
         alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 
        } 
       }); 
       timeOut = null; 
      }, 500); 
     } 
    } 
}); 

問題1:私のスクリプトは、私はそれが期待通りsetTimeOutが動作していない何らかの理由で、サーバーにあまりにも多くの通話を発信して終わります。 Ajaxの呼び出しは、ユーザーがキーを押すたびに入力するのではなく、そのような操作を行ったときにのみ行う必要があります。

問題2:何らかの理由で入力したときに入力バーが編集されません。ただし、Ajaxは機能しますが、最後のテキスト入力があります。

+0

前回の実行タイムアウトをクリアするには、 'clearTimeout(timeOut);'を追加してみてください。 –

+0

私はコード全体を読まなかったが、私が見た最初の大きな問題は、 'timeOut = null'は現在のタイムアウトをキャンセルしないということで、参照変数をnullに設定するだけである。代わりに 'clearTimeout(timeOut)'を呼び出さなければなりません。 – lexith

+0

'clearTimeout(timeOut)'に変更すると動作しなくなります。 – abhig10

答えて

1

代わりsetTimeoutでこれに取り組むしようとしているのは、あなたはAJAXによって返さ​​オブジェクトを使用して、前の呼び出しを中止することができます。これはもっとクリーンで使いやすいです。 async: false,も削除してください。

var timeOut; 
var xhr; 
$('#search input[name=\'search\']').on('keyup', function(e) { 
    // If enter - submit the search field 
    if (e.keyCode == 13) { 
     $('header input[name=\'search\']').parent().find('button').trigger('click'); 
    } 
    // Call only when length is at least 2 and the key pressed is alphanumeric 
    else if ($('#search input[name=\'search\']').val().length>2 && ((e.keyCode>=65 && e.keyCode<=90) || (e.keyCode>=97 && e.keyCode<=122))) { 
     if(xhr && xhr.readyState != 4){ 
      xhr.abort(); 
     } 
     xhr = $.ajax({ 
      url: 'ajax.php', 
      type: 'post', 
      data: 'ACTION=SEARCH&search='+$('#search input[name=\'search\']').val(), 
      dataType: 'json', 
      beforeSend: function() { 
       $('#loader-icon').show(); 
      }, 
      complete: function() { 
       $('#loader-icon').hide(); 
      }, 
      success: function(json) { 
       //$('.product-list-row').html(json); 
       $('#search-listing').html(json['html']); 
      }, 
      error: function(xhr, ajaxOptions, thrownError) { 
       alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 
      } 
     }); 
    } 
}); 
+0

複数のコールはまだ停止しません。 – abhig10

+0

以前よりもうまく動作します。私はxxxmatkoの答えを試した後、答えを受け入れるでしょう。ありがとう。 – abhig10

+0

あなたが言ったように、それはまだ複数の呼び出しを停止しません – xxxmatko

1

適切なソリューションは、両方の組み合わせで、新しいものが作られ、また、新しい要求の発射に取り組む必要がある場合、要求を実行中止。

// This is your xhr, each request save into this 
// variable, in order to be able to abort it if needed 
var xhr; 

// Wrap your event handler using the debounce function 
$("#search").on("keyup", _.debounce(function(e) { 
    // Abort running request 
    if(xhr) { 
    xhr.abort(); 
    xhr = null; 
    } 

    // Store the new request 
    xhr = $.ajax({ 
    // Search for the term $(this).val() 
    }); 
},500)); 

各keyUpイベントの検索を発射する必要はありませんが、唯一:あなたはこのようになりべきデバウンスhttp://underscorejs.org/#debounceを参照)、あなたのコードを呼び出し、そのための素晴らしい機能を持っているアンダースコアライブラリを、使用することができますユーザーが入力をやめると、debounceがあなたのためにそれを行います。要求を行う必要がある場合は、以前の結果を処理する必要はありません。

関連する問題