검색 창이 있습니다. 지금은 모든 키업을 검색합니다. 따라서 누군가“Windows”를 입력하면“W”,“Wi”,“Win”,“Wind”,“Windo”,“Window”,“Windows”와 같은 모든 키업에 대해 AJAX를 검색합니다.
지연을 원하므로 사용자가 200ms 동안 입력을 중지하면 검색 만합니다.
keyup
함수 에 이것에 대한 옵션이 없으며 시도 setTimeout
했지만 작동하지 않았습니다.
어떻게해야합니까?
검색 창이 있습니다. 지금은 모든 키업을 검색합니다. 따라서 누군가“Windows”를 입력하면“W”,“Wi”,“Win”,“Wind”,“Windo”,“Window”,“Windows”와 같은 모든 키업에 대해 AJAX를 검색합니다.
지연을 원하므로 사용자가 200ms 동안 입력을 중지하면 검색 만합니다.
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)
}
}
구현은 일련의 테스트가 포함 됩니다.
좀 더 정교한 것을 원하면 jQuery Typewatch 플러그인을 살펴보십시오 .
유형이 완료 된 후 검색하려면 전역 변수를 사용하여 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의 답변에 대한 또 다른 약간의 향상. 별도의 지연을 쉽게 허용하기 위해 다음을 사용할 수 있습니다.
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);
}
자체 지연 시간을 설정할 수 있습니다 (선택 사항, 기본값은 500ms). 그리고 함수 인수를 "클로저 방식"으로 보내십시오.
예를 들어 다음 함수를 호출하려는 경우 :
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);});
동일한 함수를 호출하지만 레이블이 다르기 때문에 독립적으로 지연시킵니다.
사용자가 텍스트 필드에 입력을 마친 후에 기능을 실행하도록 설계된 매우 간단한 접근 방식 ...
<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>
누군가가 동일한 기능을 지연시키고 외부 변수가 없으면 다음 스크립트를 사용할 수 있습니다.
function MyFunction() {
//Delaying the function execute
if (this.timer) {
window.clearTimeout(this.timer);
}
this.timer = window.setTimeout(function() {
//Execute the function code here...
}, 500);
}
이 함수는 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);
};
})();
다른 조치를 독립적으로 지연해야하는 경우 세 번째 인수를 사용하십시오.
$('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);
});
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
쿼리 요청을 하기 전에 400ms 동안 이벤트를 지연시킵니다 .
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..."/>
순수한 자바 스크립트 :
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으로 인한 고주파수 아약스 요청을 제한하기위한 코드도 만들었습니다. 이것 좀 봐:
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 */ });
});
// 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);
}