[javascript] 사용자가 입력을 멈출 때까지 .keyup () 처리기를 지연시키는 방법은 무엇입니까?

검색 창이 있습니다. 지금은 모든 키업을 검색합니다. 따라서 누군가“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 )로 전달합니다.

업데이트 2019-05-16

현대적인 환경에서 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);});


답변

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>