Matze: Funktion nach gedrückt gehaltener Maustaste

Hallo und guten Morgen!

Ich möchte, dass eine Funktion erst aufgerufen wird wenn ich einen Link eine gewisse Zeit mit der Maus gedrückt halte.
Wenn ich den Link "normal" anklicke soll zum Link gesprungen werden.

Ich denke als Event-Handler kommt nur onmousedown in Frage, oder?

Die Funktion sollte dann nach ca. 150-200ms ausgeführt werden.

Wie müsste ich das angehen?

Danke und Grüße, Matze

  1. Hi,

    Ich möchte, dass eine Funktion erst aufgerufen wird wenn ich einen Link eine gewisse Zeit mit der Maus gedrückt halte.
    Wenn ich den Link "normal" anklicke soll zum Link gesprungen werden.

    Hm. Das ist verwirrend für die User.

    Ich denke als Event-Handler kommt nur onmousedown in Frage, oder?

    onmousedown, timeout, onmouseup.

    Die Funktion sollte dann nach ca. 150-200ms ausgeführt werden.

    onmousedown einen timeout starten.
    bei timeout die Funktion aufrufen und dafür sorgen, daß der Link bei onmouseup nicht ausgeführt wird (flag setzen).
    onmouseup den timeout stoppen, bei gesetztem flag den Link nicht mehr ausführen lassen.

    (ggf. ist statt onmouseup onclick besser geeignet, mußt Du ausprobieren)

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
    1. Hallo Andreas,

      Hm. Das ist verwirrend für die User.

      in meinem Fall wird vorher auf die Funktion hingewiesen und findet sich nur im Admin-Bereich. Die Abhängigkeit von JS kann ich hier so gut verschmerzen wie die Abhängigkeit von der Maus.

      onmousedown einen timeout starten.
      bei timeout die Funktion aufrufen und dafür sorgen, daß der Link bei onmouseup nicht ausgeführt wird (flag setzen).
      onmouseup den timeout stoppen, bei gesetztem flag den Link nicht mehr ausführen lassen.

      Klingt vernünftig. Jetzt hab ich versucht mich in die Timer-Funktionen einzulesen und bin erstmal ein bisschen erschlagen :(

      Wie genau funktioniert denn setTimeout()?
      Funktioniert sowas onmousedown(setTimeout(sinnvolle_Funktion(),150));?

      Aber das würde, wenn es funkioniert, die Funktion ja einfach nach 150ms aufrufen oder?
      Wie kann ich den Timer denn abbrechen wenn die Maustaste vorher losgelassen wurde?

      Danke, Matze

      1. Hallo Matze,

        Wie genau funktioniert denn setTimeout()?

        Die Funktion benötigt eine Funktion, die nach Ablauf einer Zeit aufgerufen werden soll.

        Funktioniert sowas onmousedown(setTimeout(sinnvolle_Funktion(),150));?

        Nein, weil es nicht korrekt ist. In setTimeout muss der Name der Funktion stehen, die aufgerufen wird (ohne Klammern). Ferner würde ich meinen, dass onmousedown ein Ereignis ist und keine Funktion.

          
        var timeout = null; // damit Du das Ding auch wieder stoppen kannst.  
        obj.onmousedown = function(e) {  
          timeout = setTimeout(sinnvolle_Funktion,150);  
        }  
        
        

        Aber das würde, wenn es funkioniert, die Funktion ja einfach nach 150ms aufrufen oder?
        Wie kann ich den Timer denn abbrechen wenn die Maustaste vorher losgelassen wurde?

        Mit http://de.selfhtml.org/javascript/objekte/window.htm#clear_timeout@title=clearTimeout oder/und einer zusätzliche Flag, die von true auf false gesetzt wird.

        Mit freundlichem Gruß
        Micha

        --
        kostenlose JavaScript Spiele: Snake, MineSweeper oder Sudoku
        1. Hallo Micha,

          Wie genau funktioniert denn setTimeout()?
          Die Funktion benötigt eine Funktion, die nach Ablauf einer Zeit aufgerufen werden soll.

          und was übergibt sie dann der Funktion? Kann man denn etwas mit übergeben?

          Wie kann ich den Timer denn abbrechen wenn die Maustaste vorher losgelassen wurde?
          Mit http://de.selfhtml.org/javascript/objekte/window.htm#clear_timeout@title=clearTimeout oder/und einer zusätzliche Flag, die von true auf false gesetzt wird.

          Ich komme da irgendwie nicht weiter.
          Ich habe jetzt folgendes:

          // Funktion die der Timer aufruft  
          function test(){  
              alert(timeout);  
          }  
          // und der Timer  
          function timer() {  
              timeout = setTimeout(test, 2000);  
          }
          

          Ich habe die Zeit zum Testen auf 2000 erhöht, damit man die Verzögerung besser merkt.

          Beim ersten Klick erscheint eine 2 in der Alert-Box. Beim zweiten Mal eine 3, dann eine 4, 5 usw.

          Ich versteh setTimeout und clearTimeout irgendwie nicht :(
          Ich dachte da müsste immer eine 2 stehen oder mindestens 2, 4, 6, 8 usw.

          Ich habe auch keine Ahnung wie ich es jetzt verhindern kann die Funktion aufzurufen wenn man nicht 2000ms die Maustaste drückt.
          Oder vielleicht erstmal das die Funktion überhaupt erst nach 2000ms Maustaste drücken aufgerufen wird.

          Ich brauch wohl noch etwas Hilfe.

          Danke und Grüße, Matze

          1. Hallo Matze,

            jeder mit setTimeout erstellte Aufruf erhält eine ID, damit er bei Bedarf wieder gelöscht werden kann.

            ID = setTiemout(...)
            ...
            clearTimeout(ID);

            Gruß, Jürgen

          2. Wie genau funktioniert denn setTimeout()?
            Die Funktion benötigt eine Funktion, die nach Ablauf einer Zeit aufgerufen werden soll.

            und was übergibt sie dann der Funktion? Kann man denn etwas mit übergeben?

            Wie kann ich den Timer denn abbrechen wenn die Maustaste vorher losgelassen wurde?
            Mit http://de.selfhtml.org/javascript/objekte/window.htm#clear_timeout@title=clearTimeout oder/und einer zusätzliche Flag, die von true auf false gesetzt wird.

            Ich komme da irgendwie nicht weiter.

            ...

            Ich versteh setTimeout und clearTimeout irgendwie nicht :(

            Was verstehst du denn nicht? Bei selfhtml steht zu clearTimeout:
            Bricht einen Timeout ab, der mit der Methode nach unten setTimeout() gestartet wurde. Erwartet als Parameter die Variable, in der der Aufruf von setTimeout() gespeichert wurde.

            Struppi.

          3. Hallo Matze,

            Beim ersten Klick erscheint eine 2 in der Alert-Box. Beim zweiten Mal eine 3, dann eine 4, 5 usw.
            Ich versteh setTimeout und clearTimeout irgendwie nicht :(

            Struppi und Jürgen haben Dir ja schon gesagt, was diese Zahl bedeutet. Es ist eine Referenz vom Timeout. Damit das Script weiß, welches Timeout Du mit clearTimeout beenden möchtest, musst Du diese Referenz übergeben. Es ist ja nicht ausgeschlossen, dass Du mehre Verzögerungen nutzt.

            Du speicherst die Referenz bereits in der Variable timeout. Wenn Du diesen Timeout also abbrechen möchtest, musst Du clearTimeout(timeout) aufrufen.

            Mit freundlichem Gruß
            Micha

            --
            kostenlose JavaScript Spiele: Snake, MineSweeper oder Sudoku
            1. Hallo Micha,

              oder kurz

              clearTimeout(setTimeout("irgendeinversprechen()",1000));

              nennt sich dann Wahlversprechen.

              Gruß, Jürgen

              1. Hallo,

                achsoo...

                Ich glaube ich hab es jetzt.
                Also der Timer sollte schon bei mehreren Elementen eingesetzt werden.

                Was würde denn passieren, wenn man 2 Mauszeiger hat und nacheinander auf 2 verschiedene Elemente klickt. Bei einem hält man die Maustaste gedrückt, bei dem anderen nicht. Beide rufen ja die selbe Funktion auf.
                Woher weiß dann clearTimeout() welchen Timer es beenden soll?

                Und wozu var timeout = null;?

                Also ich habe jetzt folgenden Test:

                function test(){  
                	el.innerHTML = 'Hund';  
                }  
                  
                function stopper(){  
                	window.clearTimeout(timeout);  
                }  
                  
                function timer(element) {  
                	el = element;  
                	timeout = setTimeout(test, 1200);  
                }
                

                <h1 onmousedown="timer(this)" onmouseup="stopper()" >Katze</h1>

                Das funktioniert soweit eigentlich ganz gut.

                Danke und Grüße, Matze

                1. Hallo Matze,

                  man kann Variablen auch an Elemente "anhängen":

                  function stopper(element){  
                          window.clearTimeout(element.timeout);  
                  }  
                    
                  function timer(element) {  
                          el = element;  
                  // Vorsicht bei globalen Variablen!  
                          element.timeout = setTimeout(test, 1200);  
                  }
                  

                  Gruß, Jürgen

                  1. // Vorsicht bei globalen Variablen!

                    Inwiefern bekomm ich hier Probleme?
                    Welche Varibale ist hier überhaupt global?
                    el = element; oder element.timeout = setTimeout(edit_content, 1200);?

                    Sorry, ich bin nicht besonders fit in JavaScript.

                    Grüße, Matze

                    1. Hallo Matze,

                      alle Variablen die außerhalb von Funktionen angelegt werden, liegen im windows-Objekt und sind global, d.h. aus jeder Funktion kann auf diese Variablen zugegriffen werden. Variablen, die in einer Funktion mit var angelegt werden, sind nur in dieser Funktion und in ihren "Unterfunktionen" bekannt und werden beim Beenden der Funktion vergessen. Vergisst man hier das "var" erhält man globale Variablen. Hängt man an vorhandene Objekte Variablen an, sind diese auch von überall zu erreichen, aber die Gefahr, mit gleichnamigen Variablen aus anderen Funktionen zu kollidieren, ist geringer.

                      var global1=1;  
                      global2 = 1;  
                        
                      function tuwas() {  
                        global3 = 1;  
                        var lokal = 2;  
                      }
                      

                      Speziell in deinem Fall soll der Eventhandler ja an mehrere Elemente gehängt werden und da kollidieren die globalen Variablen bestimmt.

                      Gruß, Jürgen

                      1. Hallo,

                        Speziell in deinem Fall soll der Eventhandler ja an mehrere Elemente gehängt werden und da kollidieren die globalen Variablen bestimmt.

                        und was kann ich dagegen tun?
                        var element.timeout = setTimeout(...) gibt mir einen Fehler.

                        Grüße, Matze

                        1. Hallo Matze,

                          und was kann ich dagegen tun?
                          var element.timeout = setTimeout(...) gibt mir einen Fehler.

                          uns den Fehler mitteilen. Ich habe jetzt keine Lust, eine Testseite zu erstellen.

                          Gruß, Jürgen

                          1. Oh entschuldige, natürlich.

                            Also hier der JS-Teil:

                            function test(){  
                            	el.innerHTML = 'Hund';  
                            }  
                              
                            function rs(element){  
                            	window.clearTimeout(element.timeout);  
                            }  
                              
                            function timer(element) {  
                            	el = element;  
                            	var element.timeout = setTimeout(test, 1200);  
                            }
                            

                            Der HTML-Teil:
                            <h1 onmousedown="timer(this)" onmouseup="rs(this)" >Katze</h1>

                            Dazu sagt mir die FF-Fehlerkonsole

                            Fehler: missing ; before statement
                            Quelldatei: (....)index.html
                            Zeile: 18, Spalte: 5
                            Quelltext:
                             var element.timeout = setTimeout(test, 1200);

                            und aus der Katze wird kein Hund mehr.

                            Grüße, Matze

                            1. Hallo Matze,

                              var element.timeout = setTimeout(test, 1200);

                              das var hat hier ja auch nichts zu suchen. Hier wird ein schon vorhandenes Objekt erweitert.

                              Gruß, Jürgen

                              1. Hallo Jürgen,

                                das var hat hier ja auch nichts zu suchen. Hier wird ein schon vorhandenes Objekt erweitert.

                                tja, jetzt hab ich auch keine Ahnung mehr was du mir sonst sagen wolltest mit den globalen :(

                                Grüße, Matze

                                1. Hallo Matze,

                                  tja, jetzt hab ich auch keine Ahnung mehr was du mir sonst sagen wolltest mit den globalen :(

                                  die zu den HTML-Elementen gehörenden Objekte sind global. Wenn du so ein schon vorhandenes Objekt (egal ob global oder local) erweitern willst, hat da ein var nichts zu suchen. Mit var werden neue Variablen im Kontext der aktuellen Funktion angelegt. Lässt man var weg, was erlaubt ist, werden die Variablen im Kontext des window-Objektes angelegt, sind also global.

                                  Gruß, Jürgen

                                  1. Hallo Jürgen,

                                    ich hab keine Ahnung was du mir sagen willst oder ob du mir überhaupt was sagen willst.
                                    Ich versteh nicht was das mit meinen Funktionen zu tun hat und ob oder was ich jetzt wie ändern sollte damit die globalen Variablen nicht kollidieren.

                                    Grüße, Matze

                                    1. Hallo Matze,

                                      ich wollte dich nur warnen, da der Gebrauch von globalen Variablen zu Problemen führen kann. Ich bin in diese Falle schon derbe reingefallen. Wenn dein Script funktioniert, dann ist es doch in Ordnung.

                                      Gruß, Jürgen

                                      1. Guten Morgen Jürgen,

                                        ich wollte dich nur warnen, da der Gebrauch von globalen Variablen zu Problemen führen kann. Ich bin in diese Falle schon derbe reingefallen. Wenn dein Script funktioniert, dann ist es doch in Ordnung.

                                        aber du meintest auch, dass meine Variablen wahrscheinlich kollidieren werden.
                                        Das würde ich schon gern vermeiden, hab aber halt nicht verstanden wie :(

                                        Grüße, Matze

                                        1. Hallo Matze,

                                          ob es bei dir zu Kollisionen mit den globalen Variablen kommt, kann ich nicht sagen, ich kenne dein Gesamtprogramm nicht. Bei dem, was du bisher gezeigt hast, wird es wohl klappen.

                                          Ich habe hier mal ein Beispiel, wie man bei Eventhandlern und bei verzögert aufgerufenen Funktionen auf globale Variablen verzichten kann. Ich hänge da die Variablen an das Element mit den Event und benutze ein "Closure":

                                          function stopper(element){  
                                            window.clearTimeout(element.timeout);  
                                          }  
                                          function timer(element) {  
                                            element.timeout = setTimeout(  
                                              function() {        // Anonyme Funktion als "Closure"  
                                                var e = element;  // Eventauslösendes Element wird zwischengespeichert  
                                                test(e);}         // Der Trick ist hier, dass "element" beim Anlegen  
                                                                  // der Funktion noch bekannt ist, beim verzögerten  
                                                                  // Aufruf aber nicht mehr, "e" ist aber auch dann  
                                                                  // noch bekannt.  
                                            ,1200);  
                                          }  
                                          function test(element) {  
                                            alert(element.innerHTML);  
                                          }
                                          
                                          <div onmouseover="timer(this)" onmouseout="stopper(this)">Text1</div>  
                                          <div onmouseover="timer(this)" onmouseout="stopper(this)">Text2</div>
                                          

                                          einen guten Artikel hierzu hat Mathias geschrieben:
                                          http://aktuell.de.selfhtml.org/artikel/javascript/organisation/

                                          Gruß, Jürgen

                                          1. Hallo Jürgen,

                                            also zum besseren Verständniss zu meinem Vorhaben:
                                            Ich möchte im Admin-Bereich einer Seite eine einfache Möglichkeit zum Ändern der Inhalte einfügen.
                                            Auf den zu ändernden Inhalt kann man die Maustaste gedrückt halten und an der Stelle des Inhalts erscheint ein Textfeld und ein "Speichern"-Button.
                                            Beim Klick auf den Button wird ein AJAX-Request abgeschickt und die Änderung übernommen.

                                            Meinen aktuellen Stand haben wir ja hier zusammen erarbeitet, jetzt überlege ich, wie ich das angeklickte Element durch ein Eingabefeld+Button ersetze und ob ich dabei auch ein <form>-Element drumrum ziehen muss.

                                            Ich habe hier mal ein Beispiel, wie man bei Eventhandlern und bei verzögert aufgerufenen Funktionen auf globale Variablen verzichten kann. Ich hänge da die Variablen an das Element mit den Event und benutze ein "Closure":

                                            Danke! Ich denke das hab ich jetzt verstanden. e ist in deinem Beispiel also immer eindeutig.

                                            einen guten Artikel hierzu hat Mathias geschrieben:
                                            http://aktuell.de.selfhtml.org/artikel/javascript/organisation/

                                            Oh der Artikel sieht wirklich ziemlich gut aus.
                                            Am Anfang wird allerdings bemerkt, dass Event-Handler im HTML-Code nichts zu suchen haben.
                                            Ich bin ja nicht so fit in JS und suche jetzt danach wie es "richtig" gemacht wird.

                                            Danke und Grüße, Matze

                                            1. Hi,

                                              Meinen aktuellen Stand haben wir ja hier zusammen erarbeitet, jetzt überlege ich, wie ich das angeklickte Element durch ein Eingabefeld+Button ersetze

                                              Mit DOM-Methoden Element erzeugen und einhängen, vorhandenes Element entweder aus dem DOM entfernen, oder unsichtbar machen.

                                              und ob ich dabei auch ein <form>-Element drumrum ziehen muss.

                                              Kommt drauf an, ob du ein Formular abschicken willst.

                                              einen guten Artikel hierzu hat Mathias geschrieben:
                                              http://aktuell.de.selfhtml.org/artikel/javascript/organisation/

                                              Oh der Artikel sieht wirklich ziemlich gut aus.
                                              Am Anfang wird allerdings bemerkt, dass Event-Handler im HTML-Code nichts zu suchen haben.
                                              Ich bin ja nicht so fit in JS und suche jetzt danach wie es "richtig" gemacht wird.

                                              Dann lies den Artikel ganz durch, weiter unten kommen noch Beispiele.

                                              MfG ChrisB

                                              --
                                              Light travels faster than sound - that's why most people appear bright until you hear them speak.
                                              1. Guten Morgen ChrisB,

                                                Mit DOM-Methoden Element erzeugen und einhängen, vorhandenes Element entweder aus dem DOM entfernen, oder unsichtbar machen.

                                                ja das ist noch das Problem. Ich weiß noch nicht genau wie das geht.
                                                Wenn ich es richtig verstanden habe, muss ich dem Eltern- ein neues Kindelement verpassen.
                                                Rein vom Praktischen her wär es mir lieber ich könnte das Element einfach irgendwie ersetzen.
                                                Sowas wie ersetze Element durch Formular.
                                                Ich habe leider noch keinen Ansatz.

                                                und ob ich dabei auch ein <form>-Element drumrum ziehen muss.
                                                Kommt drauf an, ob du ein Formular abschicken willst.

                                                Sicher soll der Wert des Eingabefeldes abgesendet werden und den alten Wert in der Tabelle ersetzen, aber halt mit AJAX.
                                                Ich weiß nicht, ob ich da noch das form-Element brauch oder den Wert auch so übertragen kann.

                                                Dann lies den Artikel ganz durch, weiter unten kommen noch Beispiele.

                                                Das habe ich wohl jetzt hinbekommen.
                                                Alle relevanten Elemente haben eine Klasse bekommen.
                                                Dann überwache ich bei window onmousdown und onmouseup.
                                                Nach einem Klick oder dem Loslassen der Maustaste wird überprüft ob der Klick auf einem Element mit der Klasse war und die entsprechende Timer-Funktion aufgerufen - Timer starten oder stoppen.

                                                Klappt Prima.

                                                Grüße, Matze

                                                1. Hi,

                                                  Mit DOM-Methoden Element erzeugen und einhängen, vorhandenes Element entweder aus dem DOM entfernen, oder unsichtbar machen.

                                                  ja das ist noch das Problem. Ich weiß noch nicht genau wie das geht.

                                                  Stichworte: createElement, appendChild/replaceChild

                                                  und ob ich dabei auch ein <form>-Element drumrum ziehen muss.
                                                  Kommt drauf an, ob du ein Formular abschicken willst.

                                                  Sicher soll der Wert des Eingabefeldes abgesendet werden und den alten Wert in der Tabelle ersetzen, aber halt mit AJAX.
                                                  Ich weiß nicht, ob ich da noch das form-Element brauch oder den Wert auch so übertragen kann.

                                                  Brauchst du nicht, kannst du auch so.

                                                  MfG ChrisB

                                                  --
                                                  Light travels faster than sound - that's why most people appear bright until you hear them speak.
                                                  1. Hallo ChrisB,

                                                    Stichworte: createElement, appendChild/replaceChild

                                                    super! Danke schön!
                                                    Klappt alles wunderbar und den Button hab ich mir gespart indem ich einen Mausklick ausserhalb des Input-Feldes registriere und daraufhin der AJAX Request zum speichern abgeschickt wird.

                                                    Grüße, Matze

                2. Hi,

                  Was würde denn passieren, wenn man 2 Mauszeiger hat

                  Willst du bei der Betrachtung abzudeckender Sonderfälle nicht vielleicht doch erst nur die in der Praxis real vorkommenden betrachten ...?

                  MfG ChrisB

                  --
                  Light travels faster than sound - that's why most people appear bright until you hear them speak.
      2. Klingt vernünftig. Jetzt hab ich versucht mich in die Timer-Funktionen einzulesen und bin erstmal ein bisschen erschlagen :(

        Sie ist für deine Zwecke auch nicht unbedingt sinnvoll. Sondern wenn man eine Funktion mehrfach ausführen möchte.

        Sie funktioniert aber prinzipiell auch für dich:

        sinnvolle_Funktion().Timer(150, 1);

        Dann wird die sinnvolle Funktion nach 150ms einmal aufgerufen.

        Struppi.