sebbel: onkeyup funktion mit verzögerung ausführen

Hallo,

Zunächst: alles spielt sich in einem lokalen LAN und nur in FireFox ab und nur mit einem XmlHttpRequest Objekt (und so soll das auch bleiben).

Ich stehe vor folgendem Problem: Mit dem XmlHttpRequest Objekt lasse ich Werte in Eingabefeldern direkt bei onkeyup speichern. Tippe ich jedoch zu schnell, so wird ein Request gestartet, während noch einer im Gange ist. Ausserdem ist es ziemlich ineffizient bei jedem Tastenanschlag sofort zu speichern.

Onblur (also beim Verlassen des Feldes) kann ich aber nicht nehmen, denn dann funktioniert folgendes nicht: Habe ich den Focus noch auf einem Textfeld und klicke im Menü auf einen Eintrag (der auch einen Request über das gleiche XmlHttpRequest Objekt sendet), funktioniert die Auswahl des Eintrags nicht (und ich muss folglich 2mal klicken).

Also mein erlösender Gedanke:

Die Speicherfunktion die im onkeyup event steckt, soll erst aufgerufen werden, wenn z.B. innerhalb einer halben Sekunde kein neuer Tastenanschlag kommt.

Kannst du mir weiterhelfen? Geht das evtl. mit settimeout?

Danke für deine Hilfe!

  1. Mittlerweile habe ich es teilweise mit clearInterval und setInterval gelöst.. aber weil per XMLHTTPRequest-Object nachgeladene Javascript-Konstrukte nicht funktionieren, muss ich die Speicherfunktion in den setInterval-Aufruf einbringen.

    Funktioniert so nur leider nicht:

    savetimer = window.setInterval('loadsite('speichern.php?data='+encodeURI(escape(document.getElementById('txtData').value))+')', 1000);

    Wie muss man das syntaxtechnisch Richtig eingeben?

    1. Hallo,

      Mittlerweile habe ich es teilweise mit clearInterval und setInterval gelöst.. aber weil per XMLHTTPRequest-Object nachgeladene Javascript-Konstrukte nicht funktionieren

      Hm, wieso funktioniert das nicht, was hast du genau vor?

      JavaScripte kannst du nachladen bzw. einbinden, indem du über das DOM neue script-Elemente erzeugst und in den head einfügst.

      muss ich die Speicherfunktion in den setInterval-Aufruf einbringen.

      savetimer = window.setInterval('loadsite('speichern.php?data='+encodeURI(escape(document.getElementById('txtData').value))+')', 1000);

      encodeURI *und* escape, ist das Absicht? encodeURIComponent müsste reichen (das kodiert dann mit UTF-8).

      Wie muss man das syntaxtechnisch Richtig eingeben?

      Es geht auch alles in einer Zeile, aber warum nicht etwas übersichtlicher die Bestandteile gesondert zusammensetzen:

      var data = encodeURIComponent(document.getElementById('txtData').value));  
      var uri = "speichern.php?data=" + data;  
      var code = "loadsite('" + uri + "')";  
      window.setInterval(code, 1000);
      

      Mathias

      1. Hallo,

        Mittlerweile habe ich es teilweise mit clearInterval und setInterval gelöst.. aber weil per XMLHTTPRequest-Object nachgeladene Javascript-Konstrukte nicht funktionieren

        Hm, wieso funktioniert das nicht, was hast du genau vor?

        JavaScripte kannst du nachladen bzw. einbinden, indem du über das DOM neue script-Elemente erzeugst und in den head einfügst.

        Hast du auf die Schnelle einen Link? Ich lade bisher simpel per .innerHTML =..  nach. Dann funktioniert es nicht..

        muss ich die Speicherfunktion in den setInterval-Aufruf einbringen.

        savetimer = window.setInterval('loadsite('speichern.php?data='+encodeURI(escape(document.getElementById('txtData').value))+')', 1000);

        encodeURI *und* escape, ist das Absicht? encodeURIComponent müsste reichen (das kodiert dann mit UTF-8).

        Danke, wusste ich nicht.

        Wie muss man das syntaxtechnisch Richtig eingeben?

        Es geht auch alles in einer Zeile, aber warum nicht etwas übersichtlicher die Bestandteile gesondert zusammensetzen:

        var data = encodeURIComponent(document.getElementById('txtData').value));

        var uri = "speichern.php?data=" + data;
        var code = "loadsite('" + uri + "')";
        window.setInterval(code, 1000);

        
        >   
        > Mathias  
          
        Meine Javascript-Anweisung wird sowieso in Blöcken von PHP zusammengesetzt und als einziger String an die jeweiligen Textfelder gebunden.
        
        1. Hallo,

          JavaScripte kannst du nachladen bzw. einbinden, indem du über das DOM neue script-Elemente erzeugst und in den head einfügst.

          Hast du auf die Schnelle einen Link? Ich lade bisher simpel per .innerHTML =..  nach. Dann funktioniert es nicht..

          var script = document.createElement("script");
          script.type = "text/javascript";
          script.src = "[Adresse des nachzuladenen Scriptes, kann natürlich auch ein PHP-Script sein, dass JavaScript-Code zurückgibt]";
          document.getElementsByTagName("head")[0].appendChild(script);

          Siehe auch https://forum.selfhtml.org/?t=134613&m=873418, wie man mit XMLHttpRequest geholten JavaScript-Code ausführt.

          JSONP ist eine weitere Möglichkeit. Man übergibt einem Script einen Funktionsnamen über ?jsonp=callback. Das Script gibt dann ein JavaScript aus, dass diese Funktion aufruft und ihr Daten im JSON-Format zurückgibt, z.B. callback( { wert : "Hallo!" } ).

          Mathias

          1. var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = "[Adresse des nachzuladenen Scriptes, kann natürlich auch ein PHP-Script sein, dass JavaScript-Code zurückgibt]";
            document.getElementsByTagName("head")[0].appendChild(script);

            Vielen Dank, so müsste es funktionieren.

  2. Hallo,

    Die Speicherfunktion die im onkeyup event steckt, soll erst aufgerufen werden, wenn z.B. innerhalb einer halben Sekunde kein neuer Tastenanschlag kommt.

    Kannst du mir weiterhelfen? Geht das evtl. mit settimeout?

    Ja, genau. Du hast eine Funktion, die onkeyup aufgerufen wird. Die macht erst einmal nix anderes als einen Timeout setzen und gegebenenfalls einen laufenden Abbrechen.

    if (window.save_timeout) {
       clearTimeout(window.save_timeout);
    save_timeout = window.setTimeout("save()", 500);

    Die Funktion save() damit garantiert nur 500 Millisekunden nach dem letzten keyup aufgerufen.

    Mathias

    1. Hallo,

      Die Speicherfunktion die im onkeyup event steckt, soll erst aufgerufen werden, wenn z.B. innerhalb einer halben Sekunde kein neuer Tastenanschlag kommt.

      Kannst du mir weiterhelfen? Geht das evtl. mit settimeout?

      Ja, genau. Du hast eine Funktion, die onkeyup aufgerufen wird. Die macht erst einmal nix anderes als einen Timeout setzen und gegebenenfalls einen laufenden Abbrechen.

      if (window.save_timeout) {
         clearTimeout(window.save_timeout);
      save_timeout = window.setTimeout("save()", 500);

      Die Funktion save() damit garantiert nur 500 Millisekunden nach dem letzten keyup aufgerufen.

      Mathias

      Danke. Wie muss ich setTimeout aufrufen, wenn meine save() funktion parameter erwartet? Übrigens die "" kann man nicht verwenden, diese sind schon im onkeyup event enthalten:

      <input ... onkeyup="if (window.save_timeout) {clearTimeout(window.save_timeout); } save_timeout = window.setTimeout('save('das wäre parameter 1', 'parameter 2')', 500);"

      Theoretisch geht es, aber nur ohne Paramater.. denn diese sind auch in '-Zeichen maskiert. Und "-Zeichen kann man nicht nehmen, wegen dem  onkeyup..

      Gibt es dafür überhaupt eine Lösung? (Ausser eine save() Funktion die dann eine neue Funktion mit Paramtern ausführt..)

      1. Hallo,

        <input ... onkeyup="if (window.save_timeout) {clearTimeout(window.save_timeout); } save_timeout = window.setTimeout('save('das wäre parameter 1', 'parameter 2')', 500);"

        Gibt es dafür überhaupt eine Lösung?

        Lagere den Code in eine zentrale Funktion aus, die du im onkeyup aufrufst, dann bist du nicht an die Beschränkungen des Attributs gebunden.

        Dann kannst du auch
        window.setTimeout("save('das wäre parameter 1', 'parameter 2')", 500);
        schreiben.

        Mathias