입력 텍스트 상자에 문자를 입력하는 동안이 아니라 입력을 중지 한 직후에 이벤트를 트리거하고 싶습니다.
나는 시도했다 :
$('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 “debounce”를 사용할 수 있습니다.
$('input#username').keypress( _.debounce( function(){<your ajax call here>}, 500 ) );
즉, 500ms의 키를 누른 후에 함수 호출이 실행됩니다. 그러나 500ms 이전에 다른 키를 누르면 (다른 키 누르기 이벤트가 발생 함) 이전 함수 실행이 무시 (디 바운스)되고 새로운 500ms 타이머 후에 새 키가 실행됩니다.
추가 정보를 위해 _.debounce (func, timer, true )를 사용하면 첫 번째 함수가 실행되고 이후 500ms 타이머가 포함 된 다른 모든 키 누르기 이벤트가 무시됩니다.
답변
디 바운스가 필요합니다!
여기에 jQuery 플러그인 이 있으며 여기에 디 바운스 에 대해 알아야 할 모든 것이 있습니다 . Google에서 여기에 왔고 Underscore가 앱의 JSoup에 들어가는 방법을 찾았다면 바로 바운스가 적용 되었습니다 !
답변
세척 된 솔루션 :
$.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;
};
답변
setTimeout
변수에 할당 하고 clearTimeout
키를 누를 때 지우려면을 사용해야 합니다.
var timer = '';
$('input#username').keypress(function() {
clearTimeout(timer);
timer = setTimeout(function() {
//Your code here
}, 3000); //Waits for 3 seconds after last keypress to execute the above lines of code
});
도움이 되었기를 바랍니다.
답변
내가 만든 몇 가지 간단한 플러그인 이 있습니다. 제안 된 솔루션보다 훨씬 적은 코드가 필요하며 매우 가볍습니다 (~ 0,6kb).
먼저 언제든지 가능한 Bid
것보다 객체 를 만듭니다 bumped
. 모든 범프 는 다음 주어진 시간 동안 입찰 콜백 실행을 지연 시킵니다.
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
});
여기서 일어나는 일은 다음과 같습니다.
사용자가 키를 누를 때마다 입찰은 다음 200ms 동안 ‘지연'(범프)됩니다. 다시 ‘충돌’하지 않고 200ms가지나 가면 콜백이 실행됩니다.
또한 입찰 중지 (예 : 사용자가 esc를 누르거나 외부 입력을 클릭 한 경우)와 즉시 콜백을 완료하고 실행하는 (예 : 사용자가 Enter 키를 누를 때) 두 가지 추가 기능이 있습니다.
searchBid.stop();
searchBid.finish(valueToPass);