入力テキストボックスで文字を入力するのではなく、入力を停止した直後にイベントをトリガーしたい。
私が試した:
$('input#username').keypress(function() {
var _this = $(this); // copy of this object for further usage
setTimeout(function() {
$.post('/ajax/fetch', {
type: 'username',
value: _this.val()
}, function(data) {
if(!data.success) {
// continue working
} else {
// throw an error
}
}, 'json');
}, 3000);
});
しかし、この例では、入力されたすべての文字に対してタイムアウトが発生し、20文字を入力すると、約20のAJAXリクエストを受け取ります。
このフィドルで AJAXの代わりに単純なアラートで同じ問題を示しています。
これに対する解決策はありますか、これに対して悪いアプローチを使用していますか?
(あなたと同じように)setTimeout
を使用する必要がありますが、制限をリセットし続けることができるように参照も保存する必要があります。何かのようなもの:
//
// $('#element').donetyping(callback[, timeout=1000])
// Fires callback when a user has finished typing. This is determined by the time elapsed
// since the last keystroke and timeout parameter or the blur event--whichever comes first.
// @callback: function to be called when even triggers
// @timeout: (default=1000) timeout, in ms, to to wait before triggering event if not
// caused by blur.
// Requires jQuery 1.7+
//
;(function($){
$.fn.extend({
donetyping: function(callback,timeout){
timeout = timeout || 1e3; // 1 second default timeout
var timeoutReference,
doneTyping = function(el){
if (!timeoutReference) return;
timeoutReference = null;
callback.call(el);
};
return this.each(function(i,el){
var $el = $(el);
// Chrome Fix (Use keyup over keypress to detect backspace)
// thank you @palerdot
$el.is(':input') && $el.on('keyup keypress paste',function(e){
// This catches the backspace button in chrome, but also prevents
// the event from triggering too preemptively. Without this line,
// using tab/shift+tab will make the focused element fire the callback.
if (e.type=='keyup' && e.keyCode!=8) return;
// Check if timeout has been set. If it has, "reset" the clock and
// start over again.
if (timeoutReference) clearTimeout(timeoutReference);
timeoutReference = setTimeout(function(){
// if we made it here, our timeout has elapsed. Fire the
// callback
doneTyping(el);
}, timeout);
}).on('blur',function(){
// If we can, fire the event since we're leaving the field
doneTyping(el);
});
});
}
});
})(jQuery);
$('#example').donetyping(function(){
$('#example-output').text('Event last fired @ ' + (new Date().toUTCString()));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" id="example" />
<p id="example-output">Nothing yet</p>
次の場合に実行されます。
blur
イベント)(いずれか早い方)
解決:
これが解決策です。指定された時間の間、ユーザーが入力を停止した後に関数を実行します。
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
使用法
$('input').keyup(function() {
delay(function(){
alert('Hi, func called');
}, 1000 );
});
Underscore.jsの「デバウンス」を使用できます
$('input#username').keypress( _.debounce( function(){<your ajax call here>}, 500 ) );
これは、キーを押してから500ミリ秒後に関数呼び出しが実行されることを意味します。ただし、500msの前に別のキーを押す(別のkeypressイベントが発生する)と、前の関数の実行は無視(デバウンス)され、新しい500msのタイマーの後に新しい関数が実行されます。
追加情報については、_。debounce(func、timer、true)を使用すると、最初の関数が実行され、以降の500msタイマーで発生する他のすべてのキー押下イベントが無視されます。
デバウンスが必要です!
ここに jQueryプラグイン があり、ここに debounce について知っておく必要があるすべてがあります。 Googleからここに来て、UnderscoreがアプリのJSoupに到達した場合、デバウンスがあります baked in in !
洗浄液:
$.fn.donetyping = function(callback, delay){
delay || (delay = 1000);
var timeoutReference;
var doneTyping = function(elt){
if (!timeoutReference) return;
timeoutReference = null;
callback(elt);
};
this.each(function(){
var self = $(this);
self.on('keyup',function(){
if(timeoutReference) clearTimeout(timeoutReference);
timeoutReference = setTimeout(function(){
doneTyping(self);
}, delay);
}).on('blur',function(){
doneTyping(self);
});
});
return this;
};
いくつかの単純な plugin があります。提案されたソリューションよりもはるかに少ないコードで済み、非常に軽い(〜0,6kb)
まず、いつでもBid
にできるbumped
オブジェクトを作成します。すべてのbumpは、指定された次の時間量のBidコールバックの実行を遅らせます。
var searchBid = new Bid(function(inputValue){
//your action when user will stop writing for 200ms.
yourSpecialAction(inputValue);
}, 200); //we set delay time of every bump to 200ms
Bid
オブジェクトの準備ができたら、なんとかしてbump
にする必要があります。 keyup
event
にバンプを付けましょう。
$("input").keyup(function(){
searchBid.bump( $(this).val() ); //parameters passed to bump will be accessable in Bid callback
});
ここで何が起こるか:
ユーザーがキーを押すたびに、入札は次の200ミリ秒間「遅延」(バンプ)します。再び「ぶつかった」ことなく200ミリ秒が経過すると、コールバックが発生します。
また、入札を停止する(たとえば、ユーザーがescキーを押すか、外部入力をクリックした場合)ための2つの追加機能と、すぐにコールバックを終了して実行する(たとえば、ユーザーがEnterキーを押した場合):
searchBid.stop();
searchBid.finish(valueToPass);
setTimeout
を変数に割り当て、clearTimeout
を使用してキーを押すとクリアする必要があります。
var timer = '';
$('input#username').keypress(function() {
clearTimeout(timer);
timer = setTimeout(function() {
//Your code here
//Your code here
}, 3000); //Waits for 3 seconds after last keypress to execute the above lines of code
});
お役に立てれば。
単純なHTML/JSコードを探していましたが、見つかりませんでした。次に、onkeyup="DelayedSubmission()"
を使用して以下のコードを作成しました。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt-br" lang="pt-br">
<head><title>Submit after typing finished</title>
<script language="javascript" type="text/javascript">
function DelayedSubmission() {
var date = new Date();
initial_time = date.getTime();
if (typeof setInverval_Variable == 'undefined') {
setInverval_Variable = setInterval(DelayedSubmission_Check, 50);
}
}
function DelayedSubmission_Check() {
var date = new Date();
check_time = date.getTime();
var limit_ms=check_time-initial_time;
if (limit_ms > 800) { //Change value in milliseconds
alert("insert your function"); //Insert your function
clearInterval(setInverval_Variable);
delete setInverval_Variable;
}
}
</script>
</head>
<body>
<input type="search" onkeyup="DelayedSubmission()" id="field_id" style="WIDTH: 100px; HEIGHT: 25px;" />
</body>
</html>
なぜ時計をリセットしたいだけなのか?
var clockResetIndex = 0 ;
// this is the input we are tracking
var tarGetInput = $('input#username');
tarGetInput.on( 'keyup keypress paste' , ()=>{
// reset any privious clock:
if (clockResetIndex !== 0) clearTimeout(clockResetIndex);
// set a new clock ( timeout )
clockResetIndex = setTimeout(() => {
// your code goes here :
console.log( new Date() , tarGetInput.val())
}, 1000);
});
wordpressで作業している場合は、このすべてのコードをjQueryブロック内にラップする必要があります。
jQuery(document).ready(($) => {
/**
* @name 'navSearch'
* @version 1.0
* Created on: 2018-08-28 17:59:31
* GMT+0530 (India Standard Time)
* @author : ...
* @description ....
*/
var clockResetIndex = 0 ;
// this is the input we are tracking
var tarGetInput = $('input#username');
tarGetInput.on( 'keyup keypress paste' , ()=>{
// reset any privious clock:
if (clockResetIndex !== 0) clearTimeout(clockResetIndex);
// set a new clock ( timeout )
clockResetIndex = setTimeout(() => {
// your code goes here :
console.log( new Date() , tarGetInput.val())
}, 1000);
});
});