検索フィールドがあります。現在、すべてのキーアップを検索します。したがって、誰かが「Windows」と入力すると、「W」、「Wi」、「Win」、「Wind」、「Windo」、「Window」、「Windows」のキーアップごとにAJAXで検索が行われます。
遅延を設定したいので、ユーザーが200ミリ秒入力を停止したときにのみ検索します。
keyup
関数にはこれのオプションsetTimeout
はありません。私はを試しましたが、機能しませんでした。
どうやってやるの?
検索フィールドがあります。現在、すべてのキーアップを検索します。したがって、誰かが「Windows」と入力すると、「W」、「Wi」、「Win」、「Wind」、「Windo」、「Window」、「Windows」のキーアップごとにAJAXで検索が行われます。
遅延を設定したいので、ユーザーが200ミリ秒入力を停止したときにのみ検索します。
keyup
関数にはこれのオプションsetTimeout
はありません。私はを試しましたが、機能しませんでした。
どうやってやるの?
回答:
私はこの小さな関数を同じ目的で使用します。ユーザーが指定した時間入力を停止した後、または次のような高速で発生するイベントで関数を実行しますresize
。
function delay(callback, ms) {
var timer = 0;
return function() {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
callback.apply(context, args);
}, ms || 0);
};
}
// Example usage:
$('#input').keyup(delay(function (e) {
console.log('Time elapsed!', this.value);
}, 500));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="input">Try it:
<input id="input" type="text" placeholder="Type something here..."/>
</label>
delay
複数の実行は、この時間が経過する前に発生した場合、関数は、内部タイマーが提供される時間遅れで再開された各実行で、個々のタイマーを扱うラップ機能を返します、タイマーだけでリセットして再起動します。
タイマーが最終的に終了すると、コールバック関数が実行され、元のコンテキストと引数(この例では、jQueryのイベントオブジェクト、およびDOM要素としてthis
)が渡されます。
ES5およびES6の機能を使用して、現代の環境で関数を再実装しました。
function delay(fn, ms) {
let timer = 0
return function(...args) {
clearTimeout(timer)
timer = setTimeout(fn.bind(this, ...args), ms || 0)
}
}
タイプが完了した後に検索する場合は、グローバル変数を使用して、setTimout
呼び出しから返されたタイムアウトを保持し、clearTimeout
それがまだ発生していない場合はキャンセルして、最後のkeyup
イベント以外でタイムアウトを発生させないようにします
var globalTimeout = null;
$('#id').keyup(function(){
if(globalTimeout != null) clearTimeout(globalTimeout);
globalTimeout =setTimeout(SearchFunc,200);
}
function SearchFunc(){
globalTimeout = null;
//ajax code
}
または無名関数を使って:
var globalTimeout = null;
$('#id').keyup(function() {
if (globalTimeout != null) {
clearTimeout(globalTimeout);
}
globalTimeout = setTimeout(function() {
globalTimeout = null;
//ajax code
}, 200);
}
CMSの回答に対するもう1つのわずかな強化。個別の遅延を簡単に許可するには、以下を使用できます。
function makeDelay(ms) {
var timer = 0;
return function(callback){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
};
同じ遅延を再利用したい場合は、
var delay = makeDelay(250);
$(selector1).on('keyup', function() {delay(someCallback);});
$(selector2).on('keyup', function() {delay(someCallback);});
別の遅延が必要な場合は、
$(selector1).on('keyup', function() {makeDelay(250)(someCallback);});
$(selector2).on('keyup', function() {makeDelay(250)(someCallback);});
someApiCall
それでも複数回トリガーされます-今は入力フィールドの最終値だけで。
また、debounceなどのユーティリティメソッドを提供するunderscore.jsも確認できます。
var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);
CMSの答えに基づいて、私はこれを作りました:
jQueryをインクルードした後、以下のコードを配置します。
/*
* delayKeyup
* http://code.azerti.net/javascript/jquery/delaykeyup.htm
* Inspired by CMS in this post : http://stackoverflow.com/questions/1909441/jquery-keyup-delay
* Written by Gaten
* Exemple : $("#input").delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
*/
(function ($) {
$.fn.delayKeyup = function(callback, ms){
var timer = 0;
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(callback, ms);
});
return $(this);
};
})(jQuery);
そして単にこのように使用します:
$('#input').delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
注意:パラメーターとして渡された関数の$(this)変数が入力と一致しません
ラベルを使用した多機能呼び出しの遅延
これは私が使用するソリューションです。それはあなたが望むどんな関数でも実行を遅らせます。それは、キーダウン検索クエリである可能性があります。おそらく前または次のボタンをすばやくクリックします(そうしないと、すばやく連続してクリックすると複数のリクエストが送信され、結局使用されません)。これは、各実行時間を格納するグローバルオブジェクトを使用し、それを最新のリクエストと比較します。
その結果、最後のクリック/アクションのみが実際に呼び出されます。これらのリクエストはキューに保存されているため、同じラベルのリクエストがキューに存在しない場合、Xミリ秒後に呼び出されます。
function delay_method(label,callback,time){
if(typeof window.delayed_methods=="undefined"){window.delayed_methods={};}
delayed_methods[label]=Date.now();
var t=delayed_methods[label];
setTimeout(function(){ if(delayed_methods[label]!=t){return;}else{ delayed_methods[label]=""; callback();}}, time||500);
}
独自の遅延時間を設定できます(オプション、デフォルトは500ミリ秒)。そして、関数の引数を「クロージャ方式」で送信します。
たとえば、次の関数を呼び出す場合:
function send_ajax(id){console.log(id);}
複数のsend_ajaxリクエストを防ぐには、次を使用してリクエストを遅延させます。
delay_method( "check date", function(){ send_ajax(2); } ,600);
ラベル「チェック日付」を使用するすべてのリクエストは、600ミリ秒の時間枠内に他のリクエストが行われない場合にのみトリガーされます。この引数はオプションです
ラベルの独立性(同じターゲット関数を呼び出す)が両方を実行する:
delay_method("check date parallel", function(){send_ajax(2);});
delay_method("check date", function(){send_ajax(2);});
同じ関数を呼び出しますが、ラベルが異なるため、独立して遅延します
誰かが同じ関数を遅らせたい場合、外部変数なしで次のスクリプトを使用できます。
function MyFunction() {
//Delaying the function execute
if (this.timer) {
window.clearTimeout(this.timer);
}
this.timer = window.setTimeout(function() {
//Execute the function code here...
}, 500);
}
ユーザーがテキストフィールドへの入力を完了した後に関数を実行するように設計された超シンプルなアプローチ...
<script type="text/javascript">
$(document).ready(function(e) {
var timeout;
var delay = 2000; // 2 seconds
$('.text-input').keyup(function(e) {
console.log("User started typing!");
if(timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
myFunction();
}, delay);
});
function myFunction() {
console.log("Executing function for user!");
}
});
</script>
<textarea name="text-input" class="text-input"></textarea>
この関数は、要素を元に戻すために、Gatenの回答から関数を少し拡張します。
$.fn.delayKeyup = function(callback, ms){
var timer = 0;
var el = $(this);
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(function(){
callback(el)
}, ms);
});
return $(this);
};
$('#input').delayKeyup(function(el){
//alert(el.val());
// Here I need the input element (value for ajax call) for further process
},1000);
CMSの非常に便利なものの複数入力に関する問題について誰も言及しなかったことに驚いています。
基本的に、各入力に対して個別に遅延変数を定義する必要があります。それ以外の場合、sbが最初の入力にテキストを入力し、すぐに他の入力にジャンプして入力を開始すると、最初の入力のコールバックは呼び出されません!
他の答えに基づいて私が付いてきた以下のコードを参照してください:
(function($) {
/**
* KeyUp with delay event setup
*
* @link http://stackoverflow.com/questions/1909441/jquery-keyup-delay#answer-12581187
* @param function callback
* @param int ms
*/
$.fn.delayKeyup = function(callback, ms){
$(this).keyup(function( event ){
var srcEl = event.currentTarget;
if( srcEl.delayTimer )
clearTimeout (srcEl.delayTimer );
srcEl.delayTimer = setTimeout(function(){ callback( $(srcEl) ); }, ms);
});
return $(this);
};
})(jQuery);
このソリューションでは、setTimeout参照を入力のdelayTimer変数内に保持します。また、fazzyxが提案するように、要素の参照をコールバックに渡します。
IE6、8(comp-7)、8、およびOpera 12.11でテスト済み。
これは私にとってはうまくいきました。検索ロジックの操作を遅らせ、値がテキストフィールドに入力されたものと同じかどうかを確認しました。値が同じ場合は、検索値に関連するデータの操作を行います。
$('#searchText').on('keyup',function () {
var searchValue = $(this).val();
setTimeout(function(){
if(searchValue == $('#searchText').val() && searchValue != null && searchValue != "") {
// logic to fetch data based on searchValue
}
else if(searchValue == ''){
// logic to load all the data
}
},300);
});
キーを押すたびに呼び出される遅延機能。 jQuery 1.7.1以降が必要
jQuery.fn.keyupDelay = function( cb, delay ){
if(delay == null){
delay = 400;
}
var timer = 0;
return $(this).on('keyup',function(){
clearTimeout(timer);
timer = setTimeout( cb , delay );
});
}
使用法: $('#searchBox').keyupDelay( cb );
これはCMSに沿った解決策ですが、私にとっていくつかの重要な問題を解決します。
var delay = (function() {
var timer = {}
, values = {}
return function(el) {
var id = el.form.id + '.' + el.name
return {
enqueue: function(ms, cb) {
if (values[id] == el.value) return
if (!el.value) return
var original = values[id] = el.value
clearTimeout(timer[id])
timer[id] = setTimeout(function() {
if (original != el.value) return // solves race condition
cb.apply(el)
}, ms)
}
}
}
}())
使用法:
signup.key.addEventListener('keyup', function() {
delay(this).enqueue(300, function() {
console.log(this.value)
})
})
コードは私が好むスタイルで書かれています。セミコロンの束を追加する必要があるかもしれません。
覚えておくべきこと:
this
、期待どおりに機能します(例のように)。setTimeout
。私が使用するソリューションは、別のレベルの複雑さを追加し、たとえば実行をキャンセルできるようにしますが、これは上に構築するための良いベースです。
CMSの回答とMiguelの回答を組み合わせると、同時遅延を可能にする堅牢なソリューションが得られます。
var delay = (function(){
var timers = {};
return function (callback, ms, label) {
label = label || 'defaultTimer';
clearTimeout(timers[label] || 0);
timers[label] = setTimeout(callback, ms);
};
})();
異なるアクションを個別に遅延させる必要がある場合は、3番目の引数を使用します。
$('input.group1').keyup(function() {
delay(function(){
alert('Time elapsed!');
}, 1000, 'firstAction');
});
$('input.group2').keyup(function() {
delay(function(){
alert('Time elapsed!');
}, 1000, '2ndAction');
});
CMSの回答に基づいて、ここで新しい「遅延」メソッドを使用します。これにより、「this」が使用されます。
var delay = (function(){
var timer = 0;
return function(callback, ms, that){
clearTimeout (timer);
timer = setTimeout(callback.bind(that), ms);
};
})();
使用法:
$('input').keyup(function() {
delay(function(){
alert('Time elapsed!');
}, 1000, this);
});
使用する
mytimeout = setTimeout( expression, timeout );
ここで、expressionは実行するスクリプトで、timeoutは実行前にミリ秒単位で待機する時間です。これはスクリプトに影響を与えませんが、タイムアウトが発生するまでその部分の実行を遅らせるだけです。
clearTimeout(mytimeout);
タイムアウトがリセット/クリアされるので、まだ実行されていない限り、スクリプトは式の中で(キャンセルのように)実行されません。
CMSの回答に基づいて、値を変更しない主要なイベントを無視します。
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
var duplicateFilter=(function(){
var lastContent;
return function(content,callback){
content=$.trim(content);
if(content!=lastContent){
callback(content);
}
lastContent=content;
};
})();
$("#some-input").on("keyup",function(ev){
var self=this;
delay(function(){
duplicateFilter($(self).val(),function(c){
//do sth...
console.log(c);
});
}, 1000 );
})
bindWithDelay jQueryプラグインを使用します。
element.bindWithDelay(eventType, [ eventData ], handler(eventObject), timeout, throttle)
これが、フォームでの複数の入力を処理するために私が書いた提案です。
この関数は、入力フィールドのオブジェクトを取得し、コードに挿入します
function fieldKeyup(obj){
// what you want this to do
} // fieldKeyup
これは実際のdelayCall関数であり、複数の入力フィールドを処理します
function delayCall(obj,ms,fn){
return $(obj).each(function(){
if ( typeof this.timer == 'undefined' ) {
// Define an array to keep track of all fields needed delays
// This is in order to make this a multiple delay handling
function
this.timer = new Array();
}
var obj = this;
if (this.timer[obj.id]){
clearTimeout(this.timer[obj.id]);
delete(this.timer[obj.id]);
}
this.timer[obj.id] = setTimeout(function(){
fn(obj);}, ms);
});
}; // delayCall
使用法:
$("#username").on("keyup",function(){
delayCall($(this),500,fieldKeyup);
});
ES6から、アロー関数構文も使用できます。
この例では、keyup
ユーザーが入力を完了した後searchFunc
、クエリ要求を呼び出す前に、コードはイベントを400ミリ秒遅延させます。
const searchbar = document.getElementById('searchBar');
const searchFunc = // any function
// wait ms (milliseconds) after user stops typing to execute func
const delayKeyUp = (() => {
let timer = null;
const delay = (func, ms) => {
timer ? clearTimeout(timer): null
timer = setTimeout(func, ms)
}
return delay
})();
searchbar.addEventListener('keyup', (e) => {
const query = e.target.value;
delayKeyUp(() => {searchFunc(query)}, 400);
})
jQuery:
var timeout = null;
$('#input').keyup(function() {
clearTimeout(timeout);
timeout = setTimeout(() => {
console.log($(this).val());
}, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<input type="text" id="input" placeholder="Type here..."/>
純粋なJavascript:
let input = document.getElementById('input');
let timeout = null;
input.addEventListener('keyup', function (e) {
clearTimeout(timeout);
timeout = setTimeout(function () {
console.log('Value:', input.value);
}, 1000);
});
<input type="text" id="input" placeholder="Type here..."/>
見てみましょうオートコンプリートのプラグインを。遅延または最小文字数を指定できることは知っています。プラグインを使用していなくても、コードを調べると、自分でプラグインを実装する方法についてのアイデアが得られます。
まあ、私はまた、Keyup / Keydownによって高頻度ajaxリクエストの原因を制限するためのコードを作成しました。これをチェックしてください:
https://github.com/raincious/jQueue
次のようにクエリを実行します。
var q = new jQueue(function(type, name, callback) {
return $.post("/api/account/user_existed/", {Method: type, Value: name}).done(callback);
}, 'Flush', 1500); // Make sure use Flush mode.
そして、このようにイベントをバインドします:
$('#field-username').keyup(function() {
q.run('Username', this.val(), function() { /* calling back */ });
});
今日は少し遅れて見ましたが、他の誰かが必要になった場合に備えて、ここに置いておきます。関数を分離して再利用できるようにします。以下のコードは、stopと入力してから1/2秒待機します。
var timeOutVar
$(selector).on('keyup', function() {
clearTimeout(timeOutVar);
timeOutVar= setTimeout(function(){ console.log("Hello"); }, 500);
});
ユーザーlodash javascriptライブラリと_.debounce関数を使用
changeName: _.debounce(function (val) {
console.log(val)
}, 1000)
// Get an global variable isApiCallingInProgress
// check isApiCallingInProgress
if (!isApiCallingInProgress) {
// set it to isApiCallingInProgress true
isApiCallingInProgress = true;
// set timeout
setTimeout(() => {
// Api call will go here
// then set variable again as false
isApiCallingInProgress = false;
}, 1000);
}