Wie kann der .keyup () - Handler verzögert werden, bis der Benutzer aufhört zu tippen?

640

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

Ich möchte eine Verzögerung haben, daher wird nur gesucht, wenn der Benutzer für 200 ms aufhört zu tippen.

Es gibt keine Option dafür in der keyupFunktion, und ich habe es versucht setTimeout, aber es hat nicht funktioniert.

Wie kann ich das machen?

Ajsie
quelle
4
Duplikat von stackoverflow.com/questions/1620602/…
Roatin Marth
2
Wenn ich könnte, würde ich dies als Duplikat schließen.
a432511
7
Ich sehe keinen Schaden darin, Duplikate zu haben, solange die gegebenen und akzeptierten Antworten korrekt sind. Das Hinzufügen zur Datenbank mit Fragen muss etwas Gutes und etwas sein, nach dem man streben muss.
Mattis
14
Der Schaden ist, dass Menschen in Zukunft nicht mehr von den brillanten Antworten profitieren können, die jeder teilt, wenn es 100 gleiche Fragen gibt. Daher ist es besser, Dupes zu schließen und alle auf die ursprüngliche Frage umzuleiten, um Best Practices und Korrekturen zu finden. Weitere Informationen dazu, warum Duplikate geschlossen werden, finden Sie unter stackoverflow.com/help/duplicates .
rncrtr
14
Dies ist weitaus beliebter als die, die angeblich dupliziert wurde. Es ist besser formuliert, es hat bessere Antworten, rangiert höher bei Google usw. So viele haben von dieser Antwort profitiert. Rückblickend wäre es eine Schande gewesen, wenn dies geschlossen worden wäre. Es gibt einige triviale, die als Duplikate schlecht sind, aber dies fällt nicht in diese Kategorie.
Benutzer

Antworten:

1118

Ich verwende diese kleine Funktion für den gleichen Zweck und führe eine Funktion aus, nachdem der Benutzer für eine bestimmte Zeit oder bei Ereignissen, die mit hoher Geschwindigkeit ausgelöst werden, nicht mehr tippt, wie z 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:

Die delayFunktion gibt eine umschlossene Funktion zurück, die intern einen einzelnen Timer verarbeitet. 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 erneut gestartet.

Wenn der Timer endgültig endet, wird die Rückruffunktion ausgeführt, wobei der ursprüngliche Kontext und die ursprünglichen Argumente übergeben werden (in diesem Beispiel das Ereignisobjekt von jQuery 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 Implementierung wird mit a abgedeckt Reihe von Tests .

Werfen Sie einen Blick auf das jQuery Typewatch- Plugin , um etwas Anspruchsvolleres zu erhalten .

CMS
quelle
64
Eine weitere Alternative: github.com/bgrins/bindWithDelay/blob/master/bindWithDelay.js . Es funktioniert ziemlich genau so, wie Sie es beschrieben haben. Ich habe gerade festgestellt, dass ich dieses Muster häufig verwendet habe, und es als jQuery-Plugin implementiert, um die Syntax zu vereinfachen. Hier ist eine Demoseite
Brian Grinstead
2
Ich habe anfangs die Anzahl der eingegebenen Buchstaben fest codiert. Dieser Ansatz ist glatt wie Melasse (ohne Schwefel)
Har
2
Wenn ich dies mit einem $ .post () verwende, sendet es alles, was gleichzeitig eingegeben wurde, aber es sendet es so oft, wie ich ein Keyup hatte. Gibt es eine Möglichkeit, NUR zu senden, wenn das Timeout abgelaufen ist?
ntgCleaner
7
Dies funktioniert jedoch nicht, wenn ich zwei oder mehr verschiedene Funktionen aufrufe, die eine individuelle Verzögerung erfordern. Ich habe diese Lösung stattdessen stackoverflow.com/a/30503848/1834212
Miguel
4
Ich empfehle das Plugin 'bindWithDelay', das im oberen Kommentar verlinkt ist. Aber ich schlage @ Hazeriders Antwort auf diese Frage vor (unten - stackoverflow.com/a/19259625/368896 ), die besser ist als diese Antwort und es lohnt sich, sie zu studieren, um die Idee hinter einer einfachen, raffinierten Bindung zu verstehen, um verschiedene Timer für verschiedene Elemente zuzulassen - die Das gleiche Prinzip wie im obigen Plugin-Code, aber leichter zu verstehen.
Dan Nissenbaum
60

Wenn Sie nach Abschluss des Typs suchen möchten, verwenden Sie eine globale Variable, um das von Ihrem setTimoutAnruf zurückgegebene clearTimeoutZeitlimit zu speichern und es mit einem zu beenden, wenn es noch nicht aufgetreten ist, damit das Zeitlimit nur beim letzten keyupEreignis ausgelöst wird

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);  
}   
RHicke
quelle
39

Eine weitere leichte Verbesserung der Antwort von CMS. Um separate Verzögerungen einfach zuzulassen, 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 wiederverwenden möchten, tun Sie dies 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 dies tun

$(selector1).on('keyup', function() {makeDelay(250)(someCallback);});
$(selector2).on('keyup', function() {makeDelay(250)(someCallback);});
Paschover
quelle
1
Interessant, dass die Lösung mit mehr als 600 Upvotes zum Zeitpunkt, an dem ich diesen Kommentar schreibe, nicht so gut ist wie diese Antwort mit nur 2 Upvotes (einschließlich meiner). Deutlich überlegen, da es mehrere Widgets unterstützt, die die Verzögerung entweder teilen oder nicht teilen können. Hervorragende Antwort.
Dan Nissenbaum
... Obwohl das jQuery-Plugin im Kommentar unter der Antwort auch separate Timer für separate Elemente verarbeitet und auch das Argument für Gas und Ereignis hinzufügt: github.com/bgrins/bindWithDelay/blob/master/bindWithDelay.js. Der allgemeine Ansatz dieses Plugins ist der gleiche wie Ihr Code. Es lohnt sich daher, Ihren Code sorgfältig zu studieren, um ihn für seine Einfachheit zu verstehen, bevor Sie versuchen, das komplexere Plugin zu verstehen. Ich empfehle dieses Plugin zwar - aber wenn Sie weder Gas noch Ereignisdaten benötigen, ist Ihr Code großartig! Zwei gute Möglichkeiten. Vielen Dank!
Dan Nissenbaum
1
Hmm, es verzögert sich für mich, wird aber someApiCallimmer noch mehrmals ausgelöst - jetzt nur mit dem Endwert des Eingabefeldes.
Roelant
30

Sie können sich auch underscore.js ansehen , das Dienstprogrammmethoden wie debounce bietet :

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);
meleyal
quelle
Das gleiche ist auch verfügbar in Lodash - lodash.com/docs/#debounce
Adarsh ​​Madrecha
14

Basierend auf der Antwort von CMS habe ich Folgendes gemacht:

Geben Sie den folgenden Code ein, nachdem Sie jQuery eingeschlossen haben:

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

Und einfach so verwenden:

$('#input').delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);

Achtung: Die Variable $ (this) in der als Parameter übergebenen Funktion stimmt nicht mit der Eingabe überein

Gaten
quelle
11

Verzögern Sie Multifunktionsaufrufe mithilfe von Etiketten

Dies ist die Lösung, mit der ich arbeite. Dies verzögert die Ausführung einer beliebigen Funktion . Dies kann die Keydown-Suchabfrage sein, möglicherweise das schnelle Klicken auf die vorherigen oder nächsten Schaltflächen (die andernfalls mehrere Anfragen senden würden, wenn schnell kontinuierlich geklickt wird, und schließlich nicht verwendet werden). Dabei wird ein globales Objekt verwendet, das jede Ausführungszeit speichert und mit der aktuellsten Anforderung vergleicht.

Das Ergebnis ist also, dass nur der letzte Klick / die letzte Aktion tatsächlich aufgerufen wird, da diese Anforderungen in einer Warteschlange gespeichert sind, und dass nach Ablauf der X Millisekunden keine andere Anforderung mit derselben Bezeichnung in der Warteschlange vorhanden ist!

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

Sie können Ihre eigene Verzögerungszeit einstellen (optional, standardmäßig 500 ms). Und senden Sie Ihre Funktionsargumente "abschließend".

Zum Beispiel, wenn Sie die folgende Funktion aufrufen möchten:

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

Um mehrere send_ajax-Anforderungen zu vermeiden, verzögern Sie sie mit:

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

Jede Anfrage, die das Label "Prüfdatum" verwendet, wird nur ausgelöst, wenn innerhalb des Zeitrahmens von 600 Millisekunden keine andere Anfrage gestellt wird. Dieses Argument ist optional

Beschriften Sie die Unabhängigkeit (rufen Sie dieselbe Zielfunktion auf), führen Sie jedoch beide aus:

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

Dies führt dazu, dass dieselbe Funktion aufgerufen wird, sie jedoch unabhängig voneinander verzögert werden, da ihre Beschriftungen unterschiedlich sind

Miguel
quelle
Ich verwende Ihren Code in einem Projekt, an dem ich arbeite, und habe Schwierigkeiten damit. Es verzögert eigentlich nichts. Ich dachte, Sie möchten vielleicht Hilfe sehen / leisten. stackoverflow.com/questions/51393779/…
KDJ
9

Wenn jemand dieselbe Funktion ohne externe Variable verzögern möchte, kann er das nächste Skript verwenden:

function MyFunction() {

    //Delaying the function execute
    if (this.timer) {
        window.clearTimeout(this.timer);
    }
    this.timer = window.setTimeout(function() {

        //Execute the function code here...

    }, 500);
}
Roy Shoa
quelle
1
Großartig! Einfache Lösung, die gut funktioniert!
Fellipe Sanches
1
Ich mag diesen. Nicht gerade wiederverwendbar, aber leicht zu verstehen.
Vincent
9

Super einfacher Ansatz, mit dem eine Funktion ausgeführt werden kann, nachdem ein Benutzer ein Textfeld eingegeben hat ...

<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>
HoldOffHunger
quelle
1
Vielen Dank! Die oben genannten populären Antworten haben nicht funktioniert ... aber Ihr Vorschlag hat perfekt funktioniert.
user2662680
1
2020 funktioniert immer noch
Romel Indemne
7

Diese Funktion erweitert die Funktion von Gatens Antwort ein wenig, um das Element zurückzubekommen:

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

Fazzyx
quelle
6

Dies funktionierte bei mir, wo ich die Suchlogik verzögere und überprüfe, ob der Wert mit dem im Textfeld eingegebenen übereinstimmt. Wenn der Wert gleich ist, führe ich die Operation für die Daten aus, die sich auf den Suchwert beziehen.

$('#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);
});
Sagar Gala
quelle
funktioniert nicht wie erwartet - die Anzahl der Abrufe ist gleich, nur um 300 ms verzögert - Sie müssen die Funktion clearTimeout () bei jedem Tastendruck verwenden, bevor Sie setTimeout () ausführen
Picard
In diesem Fall müssen Sie clearTimeout nicht verwenden. Die Bedingung searchValue == $ ('# searchText'). Val () in setTimeout stellt sicher, dass der Wert mit dem Wert vor 300 ms übereinstimmt. Lassen Sie mich wissen, ob dies sinnvoll ist. Vielen Dank.
Sagar Gala
5

Ich bin überrascht, dass niemand das Problem mit Mehrfacheingaben in CMS erwähnt hat.

Grundsätzlich müssten Sie die Verzögerungsvariable für jeden Eingang einzeln definieren. Andernfalls, wenn jdn Text in die erste Eingabe einfügt und schnell zu einer anderen Eingabe springt und mit der Eingabe beginnt, wird der Rückruf für die erste NICHT aufgerufen!

Siehe den Code unten, mit dem ich basierend auf anderen Antworten gekommen bin:

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

Diese Lösung behält die setTimeout-Referenz in der delayTimer-Variablen der Eingabe. Es wird auch die Referenz des Elements an den Rückruf übergeben, wie von fazzyx vorgeschlagen.

Getestet in IE6, 8 (comp - 7), 8 und Opera 12.11.

jszoja
quelle
Ich habe es versucht, kann aber beim ersten Keyup nicht richtig arbeiten.
Lars Thorén
4

Verzögerungsfunktion zum Aufrufen bei jeder Eingabe. jQuery 1.7.1 oder höher erforderlich

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

Verwendungszweck: $('#searchBox').keyupDelay( cb );

Vinay Aggarwal
quelle
3

Aufbauend auf der Antwort von CMS gibt es hier eine neue Verzögerungsmethode, die "dies" in ihrer Verwendung beibehält:

var delay = (function(){
  var timer = 0;
  return function(callback, ms, that){
    clearTimeout (timer);
    timer = setTimeout(callback.bind(that), ms);
  };
})();

Verwendungszweck:

$('input').keyup(function() {
    delay(function(){
      alert('Time elapsed!');
    }, 1000, this);
});
mga911
quelle
2

Verwenden

mytimeout = setTimeout( expression, timeout );

Dabei ist expression das auszuführende Skript und timeout die Wartezeit in Millisekunden, bevor es ausgeführt wird. Dadurch wird das Skript NICHT beschädigt, sondern die Ausführung dieses Teils wird einfach verzögert, bis das Timeout abgeschlossen ist.

clearTimeout(mytimeout);

setzt das Zeitlimit zurück / löscht es, sodass das Skript nicht im Ausdruck (wie ein Abbruch) ausgeführt wird, solange es noch nicht ausgeführt wurde.

Mark Schultheiss
quelle
2

Dies ist eine Lösung im Sinne von CMS, löst jedoch einige wichtige Probleme für mich:

  • Unterstützt mehrere Eingänge, Verzögerungen können gleichzeitig ausgeführt werden.
  • Ignoriert wichtige Ereignisse, die den Wert nicht geändert haben (z. B. Strg, Alt + Tab).
  • Löst eine Racebedingung (wenn der Rückruf ausgeführt wird und der Wert bereits geändert wurde).
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)
            }
        }
    }
}())

Verwendungszweck:

signup.key.addEventListener('keyup', function() {
    delay(this).enqueue(300, function() {
        console.log(this.value)
    })
})

Der Code ist in einem Stil geschrieben, den ich mag. Möglicherweise müssen Sie eine Reihe von Semikolons hinzufügen.

Dinge zu beachten:

  • Eine eindeutige ID wird basierend auf der Formular-ID und dem Eingabenamen generiert. Sie müssen daher definiert und eindeutig sein, oder Sie können sie an Ihre Situation anpassen.
  • verzögern gibt ein Objekt zurück, das sich leicht für Ihre eigenen Bedürfnisse erweitern lässt.
  • Das ursprüngliche Element, das für die Verzögerung verwendet wird, ist an den Rückruf gebunden und thisfunktioniert also wie erwartet (wie im Beispiel).
  • Der leere Wert wird bei der zweiten Validierung ignoriert.
  • Achten Sie auf die Warteschlange , es werden zuerst Millisekunden erwartet, das ist mir lieber, aber Sie können die Parameter entsprechend ändernsetTimeout .

Die von mir verwendete Lösung erhöht die Komplexität zusätzlich, sodass Sie beispielsweise die Ausführung abbrechen können. Dies ist jedoch eine gute Basis, auf der Sie aufbauen können.

Jaime Gómez
quelle
2

Basierend auf der Antwort von CMS werden nur die Schlüsselereignisse ignoriert, die den Wert nicht ändern.

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


})
Anderson
quelle
2

Die Kombination der CMS-Antwort mit der von Miguel ergibt eine robuste Lösung, die gleichzeitige Verzögerungen ermöglicht.

var delay = (function(){
    var timers = {};
    return function (callback, ms, label) {
        label = label || 'defaultTimer';
        clearTimeout(timers[label] || 0);
        timers[label] = setTimeout(callback, ms);
    };
})();

Wenn Sie verschiedene Aktionen unabhängig voneinander verzögern müssen, verwenden Sie das dritte Argument.

$('input.group1').keyup(function() {
    delay(function(){
        alert('Time elapsed!');
    }, 1000, 'firstAction');
});

$('input.group2').keyup(function() {
    delay(function(){
        alert('Time elapsed!');
    }, 1000, '2ndAction');
});
Frédéric
quelle
1

Verwenden Sie das bindWithDelay jQuery-Plugin:

element.bindWithDelay(eventType, [ eventData ], handler(eventObject), timeout, throttle)
Vebjorn Ljosa
quelle
1
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
};
krut1
quelle
1

Hier ist ein Vorschlag, den ich geschrieben habe und der sich um mehrere Eingaben in Ihrem Formular kümmert.

Diese Funktion ruft das Objekt des Eingabefeldes in Ihren Code ein

function fieldKeyup(obj){
    //  what you want this to do

} // fieldKeyup

Dies ist die eigentliche delayCall-Funktion, die sich um mehrere Eingabefelder kümmert

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

Verwendungszweck:

$("#username").on("keyup",function(){
    delayCall($(this),500,fieldKeyup);
});
egpo
quelle
1

Ab ES6 kann auch die Pfeilfunktionssyntax verwendet werden .

In diesem Beispiel verzögert der Code das keyupEreignis um 400 ms, nachdem Benutzer die Eingabe beendet haben, bevor sie searchFunceine Abfrageanforderung stellen.

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);
})
Dat Nguyen
quelle
1

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

Ali Nasr
quelle
0

Schauen Sie sich das Autocomplete- Plugin an. Ich weiß, dass Sie damit eine Verzögerung oder eine Mindestanzahl von Zeichen angeben können. Selbst wenn Sie das Plugin nicht verwenden, erhalten Sie beim Durchsehen des Codes einige Ideen, wie Sie es selbst implementieren können.

Tvanfosson
quelle
0

Nun, ich habe auch einen Code für die Begrenzung der Hochfrequenz-Ajax-Anfrage von Keyup / Keydown erstellt. Überprüfen Sie dies heraus:

https://github.com/raincious/jQueue

Führen Sie Ihre Anfrage folgendermaßen aus:

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.

Und Ereignis wie folgt binden:

$('#field-username').keyup(function() {
    q.run('Username', this.val(), function() { /* calling back */ });
});

quelle
0

Habe das heute etwas spät gesehen, möchte es aber nur hier einfügen, falls jemand anderes es braucht. Trennen Sie einfach die Funktion, um sie wiederverwendbar zu machen. Der folgende Code wartet nach dem Eingeben von stop eine halbe Sekunde.

    var timeOutVar
$(selector).on('keyup', function() {

                    clearTimeout(timeOutVar);
                    timeOutVar= setTimeout(function(){ console.log("Hello"); }, 500);
                });
Chungtinhlakho
quelle
0

Benutzer lodash Javascript-Bibliothek und verwenden Sie die Funktion _.debounce

changeName: _.debounce(function (val) {
  console.log(val)                
}, 1000)
Amir Ur Rehman
quelle
0
// 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);
}
Bharat Chaudhari
quelle