programing

사용자가 입력을 중지할 때까지 .keyup() 핸들러를 지연하려면 어떻게 해야 합니까?

projobs 2023. 2. 3. 21:19
반응형

사용자가 입력을 중지할 때까지 .keyup() 핸들러를 지연하려면 어떻게 해야 합니까?

검색 필드가 있습니다.지금은 모든 키업을 검색합니다.따라서 "Windows"를 입력하면 "W", "Wi", "Win", "Win", "Wind", "Windo", "Window", "Window" 등의 모든 키를 AJAX에서 검색합니다.

200밀리초 동안 사용자가 입력을 중단했을 때만 검색되도록 지연을 만들고 싶습니다.

.keyup는 능, 리, 리, 리, 그, 도, 도, function, function, function, function, function, function, function, functionsetTimeout하지만 소용없었다.

내가 어떻게 그럴 수 있을까?

한 후 가 높은예: 이벤트 발생 시)를합니다.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함수는 개별 타이머를 내부적으로 처리하는 래핑된 함수를 반환합니다.각 실행 시 타이머는 지정된 시간 지연으로 재시작됩니다.이 시간이 경과하기 전에 여러 번의 실행이 발생하면 타이머는 리셋되고 다시 시작됩니다.

)가 됩니다.DOM 요소는 "JQuery" (JQuery) 입니다.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 플러그인을 보시기 바랍니다.

된 후 를 사용하여 "에서합니다.setTimoutclearTimeoutkeyup

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);

설명.

변수를 사용하여 타임아웃 함수를 저장합니다.그런 다음 를 사용하여 이 변수에서 활성 타임아웃 기능을 지우고 를 사용하여 다시 활성 타임아웃 기능을 설정합니다.우리는 달린다clearTimeout()첫째, 사용자가 "hello"를 입력할 경우 사용자가 "o" 키를 누른 직후(각 문자당 한 번이 아니라) 기능을 실행해야 하기 때문입니다.

작업 데모

사용자가 텍스트 필드에 입력을 완료한 후 함수를 실행하도록 설계된 매우 간단한 접근법입니다.

    $(document).ready(function(e) {
        var timeout;
        var delay = 2000;   // 2 seconds

        $('.text-input').keyup(function(e) {
            $('#status').html("User started typing!");
            if(timeout) {
                clearTimeout(timeout);
            }
            timeout = setTimeout(function() {
                myFunction();
            }, delay);
        });

        function myFunction() {
            $('#status').html("Executing function for user!");
        }
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Status: <span id="status">Default Status</span><br>
<textarea name="text-input" class="text-input"></textarea>

CMS의 답변을 바탕으로 다음과 같이 작성했습니다.

include 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);

주의: 매개 변수로 전달된 함수의 $(이) 변수가 입력과 일치하지 않습니다.

라벨을 사용한 다기능 콜 지연

이것이 제가 다루는 해결책입니다.원하는 기능에 대한 실행이 지연됩니다.키다운 검색 쿼리, 이전 버튼 또는 다음 버튼을 빠르게 클릭할 수 있습니다(그렇지 않으면 빠르게 계속 클릭하면 여러 요청이 전송되어 결국 사용되지 않습니다).각 실행 시간을 저장하는 글로벌개체를 사용하여 최신 요구와 비교합니다.

따라서 이러한 요구는 큐에 저장되기 때문에 마지막 클릭/액션만 실제로 호출됩니다.같은 라벨을 가진 다른 요구가 큐에 존재하지 않으면 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).그리고 함수 인수를 "닫기 방식"으로 보내십시오.

예를 들어, Bellow 함수를 호출하려는 경우:

function send_ajax(id){console.log(id);}

여러 send_ajax 요청을 방지하려면 다음 명령을 사용하여 요청을 지연합니다.

delay_method( "check date", function(){ send_ajax(2); } ,600);

"check date" 라벨을 사용하는 모든 요청은 600밀리초 동안 다른 요청이 이루어지지 않은 경우에만 트리거됩니다.이 인수는 옵션입니다.

라벨 독립성(동일한 타깃 함수 호출) 단, 둘 다 실행:

delay_method("check date parallel", function(){send_ajax(2);});
delay_method("check date", function(){send_ajax(2);});

같은 함수를 호출하지만 라벨이 다르기 때문에 개별적으로 지연됩니다.

j쿼리:

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..."/>

외부 변수를 사용하지 않고 동일한 기능을 지연시키고 싶은 경우 다음 스크립트를 사용할 수 있습니다.

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);

http://jsfiddle.net/Us9bu/2/

CMS에서 여러 입력에 관한 문제를 언급하는 사람이 아무도 없다는 것이 놀랍습니다.

기본적으로 각 입력에 대해 지연 변수를 개별적으로 정의해야 합니다.그렇지 않으면 첫 번째 입력에 텍스트를 입력한 후 다른 입력으로 빠르게 이동하여 입력을 시작하면 첫 번째 입력에 대한 콜백이 호출되지 않습니다.

기타 답변에 따라 제공된 아래 코드를 참조하십시오.

(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 );
  });
}

: 사법 usage :$('#searchBox').keyupDelay( cb );

ES6부터는 화살표 함수 구문도 사용할 수 있습니다.

예에서는 가 지연됩니다.keyup후 동안 발생 후 400ms를 호출합니다.searchFunc회를요요요요

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);
})

업데이트된 형식 스크립트 버전:

const delayKeyUp = (() => {
  let timer: NodeJS.Timeout;
  return (func: Function, ms: number) => {
    timer ? clearTimeout(timer) : null;
    timer = setTimeout(() => func(), ms);
  };
})();

이것은 CMS와 같은 솔루션이지만, 몇 가지 중요한 문제를 해결합니다.

  • 여러 입력을 지원하며 지연을 동시에 실행할 수 있습니다.
  • 값을 변경하지 않은 주요 이벤트(예: Ctrl, Alt+Tab)를 무시합니다.
  • 레이스 조건(콜백이 실행되고 값이 이미 변경된 경우)을 해결합니다.
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)
    })
})

코드는 제가 좋아하는 스타일로 작성되어 있기 때문에 세미콜론을 여러 개 추가해야 할 수 있습니다.

유의사항:

  • 양식 ID 및 입력 이름을 기준으로 고유 ID가 생성되므로 정의되고 고유해야 합니다. 그렇지 않으면 상황에 맞게 조정할 수 있습니다.
  • delay는 필요에 따라 쉽게 확장할 수 있는 개체를 반환합니다.
  • 때문에, 「 」는 「 」입니다.this는 예상대로 동작합니다(예시와 같음).
  • 두 번째 검증에서는 빈 값은 무시됩니다.
  • enqueue에 주의해 주세요.먼저 밀리초를 예상합니다만, 일치하도록 파라미터를 전환하는 것이 좋습니다.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);
});

사용하다

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 );


})

일정 시간 후에 작업을 수행하고 특정 이벤트 후에 타이머를 리셋하려면 다음과 같이 하십시오.keyup, 최고의 솔루션은clearTimeout그리고.setTimeout메서드:

// declare the timeout variable out of the event listener or in the global scope
var timeout = null;

$(".some-class-or-selector-to-bind-event").keyup(function() {
    clearTimeout(timout); // this will clear the recursive unneccessary calls
    timeout = setTimeout(() => {
         // do something: send an ajax or call a function here
    }, 2000);
    // wait two seconds

});

bind With Delay jQuery 플러그인 사용:

element.bindWithDelay(eventType, [ eventData ], handler(eventObject), timeout, throttle)
var globalTimeout = null;  
$('#search').keyup(function(){
  if(globalTimeout != null) clearTimeout(globalTimeout);  
  globalTimeout =setTimeout(SearchFunc,200);  
});
function SearchFunc(){  
  globalTimeout = null;  
  console.log('Search: '+$('#search').val());
  //ajax code
};

여기 당신의 양식에 여러 입력을 처리하기 위해 제가 작성한 제안서가 있습니다.

이 함수는 입력 필드의 개체를 가져옵니다. 코드를 입력하십시오.

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);
});

사용자 lodash javascript 라이브러리 및 _.debounce 함수 사용

changeName: _.debounce(function (val) {
  console.log(val)                
}, 1000)

자동 완성 플러그인을 확인합니다.지연 또는 최소 문자 수를 지정할 수 있는 것으로 알고 있습니다.플러그 인을 사용하지 않아도 코드를 통해 직접 구현 방법에 대한 아이디어를 얻을 수 있습니다.

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);
                });
// 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);
}

언급URL : https://stackoverflow.com/questions/1909441/how-to-delay-the-keyup-handler-until-the-user-stops-typing

반응형