782 Stimmen

Wie kann man den .keyup()-Handler verzögern, bis der Benutzer aufhört zu tippen?

Ich habe ein Suchfeld. Im Moment sucht es nach jeder Tastenkombination. Wenn also jemand "Windows" eingibt, wird mit AJAX nach jedem Keyup gesucht: "W", "Wi", "Win", "Wind", "Windo", "Fenster", "Windows".

Ich möchte eine Verzögerung haben, so dass nur gesucht wird, wenn der Benutzer 200 ms lang aufhört zu tippen.

Es gibt keine entsprechende Option in der keyup Funktion, und ich habe versucht setTimeout aber es hat nicht funktioniert.

Wie kann ich das tun?

1330voto

Christian C. Salvadó Punkte 763569

Ich verwende diese kleine Funktion für den gleichen Zweck, indem ich eine Funktion ausführe, nachdem der Benutzer für eine bestimmte Zeitspanne aufgehört hat zu tippen, oder in Ereignissen, die mit einer hohen Rate ausgelöst werden, wie 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>

Wie es funktioniert:

El delay Funktion gibt eine gepackte Funktion zurück, die intern einen individuellen Timer handhabt. Bei jeder Ausführung wird der Timer mit der angegebenen Zeitverzögerung neu gestartet, wenn mehrere Ausführungen vor Ablauf dieser Zeit erfolgen, wird der Timer einfach zurückgesetzt und neu gestartet.

Wenn der Timer schließlich endet, wird die Callback-Funktion ausgeführt, wobei der ursprüngliche Kontext und die Argumente übergeben werden (in diesem Beispiel das jQuery-Ereignisobjekt und das DOM-Element als this ).

UPDATE 2019-05-16

Ich habe die Funktion mit ES5- und ES6-Funktionen für moderne Umgebungen neu implementiert:

function delay(fn, ms) {
  let timer = 0
  return function(...args) {
    clearTimeout(timer)
    timer = setTimeout(fn.bind(this, ...args), ms || 0)
  }
}

Die Umsetzung ist mit einer eine Reihe von Tests .

Wenn Sie etwas Anspruchsvolleres suchen, sollten Sie einen Blick auf die jQuery Typewatch Plugin.

70voto

RHicke Punkte 3284

Wenn Sie eine Suche durchführen wollen, nachdem der Typ fertig ist, verwenden Sie eine globale Variable, um die Zeitüberschreitung zu speichern, die von Ihrer setTimout aufzurufen und ihn mit einer clearTimeout wenn es noch nicht geschehen ist, so dass die Zeitüberschreitung nur bei der letzten Eingabe ausgelöst wird. keyup Veranstaltung

var globalTimeout = null;  
$('#id').keyup(function(){
  if(globalTimeout != null) clearTimeout(globalTimeout);  
  globalTimeout =setTimeout(SearchFunc,200);  
}   
function SearchFunc(){  
  globalTimeout = null;  
  //ajax code
}

Oder mit einer anonymen Funktion:

var globalTimeout = null;  
$('#id').keyup(function() {
  if (globalTimeout != null) {
    clearTimeout(globalTimeout);
  }
  globalTimeout = setTimeout(function() {
    globalTimeout = null;  

    //ajax code

  }, 200);  
}

47voto

Paschover Punkte 798

Eine weitere kleine Verbesserung der Antwort von CMS. Um auf einfache Weise separate Verzögerungen zu ermöglichen, können Sie Folgendes verwenden:

function makeDelay(ms) {
    var timer = 0;
    return function(callback){
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    };
};

Wenn Sie dieselbe Verzögerung wieder verwenden wollen, machen Sie einfach

var delay = makeDelay(250);
$(selector1).on('keyup', function() {delay(someCallback);});
$(selector2).on('keyup', function() {delay(someCallback);});

Wenn Sie separate Verzögerungen wünschen, können Sie Folgendes tun

$(selector1).on('keyup', function() {makeDelay(250)(someCallback);});
$(selector2).on('keyup', function() {makeDelay(250)(someCallback);});

32voto

meleyal Punkte 30244

Sie können sich auch ansehen unterstrich.js , die Dienstprogrammmethoden wie Entprellung :

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

19voto

Ali Punkte 362

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

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X