webentwicklung-frage-antwort-db.com.de

Wie verwendet man sowohl onclick als auch ondblclick für ein Element?

Ich habe ein Element auf meiner Seite, an das ich Ereignishandler für onclick und ondblclick anhängen muss. Wenn ein einzelner Klick erfolgt, sollte dies etwas anderes als ein Doppelklick sein. Als ich anfing, diese Arbeit zu machen, fing mein Kopf an sich zu drehen. Offensichtlich wird onclick immer ausgelöst, wenn Sie doppelklicken. Also habe ich versucht, eine Timeout-basierte Struktur wie diese zu verwenden ...

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  el.onclick = function() {
    timer = setTimeout(function() { alert('Single'); }, 150);        
  }

  el.ondblclick = function() {
    clearTimeout(timer);
    alert('Double');
  }
}

Aber ich habe inkonsistente Ergebnisse (mit IE8). Es funktionierte oft richtig, aber manchmal bekam ich zweimal die Warnung "Single".

Hat das schon mal jemand gemacht? Gibt es einen effektiveren Weg?

24
Josh Stodola

Wie Matt hatte ich eine viel bessere Erfahrung, als ich den Timeout-Wert leicht erhöhte. Um das Problem der Doppelklickauslösung durch ein doppeltes Klicken (das ich mit dem höheren Timer ohnehin nicht reproduzieren konnte) zu mildern, habe ich dem Einzelklick-Handler eine Zeile hinzugefügt:

el.onclick = function() {
    if (timer) clearTimeout(timer);
    timer = setTimeout(function() { alert('Single'); }, 250);        
}

Wenn der Klick bereits aktiviert ist, wird er automatisch gelöscht, um doppelte 'Single'-Warnungen zu vermeiden.

23
Soldarnal

Wenn Sie zwei Warnungen erhalten, scheint Ihr Schwellenwert für das Erkennen eines Doppelklicks zu klein zu sein. Versuchen Sie, 150 bis 300 ms zu erhöhen. 

Ich bin auch nicht sicher, ob Ihnen garantiert ist, in welcher Reihenfolge Click und Dblclick ausgelöst werden. Wenn also Ihr dblclick ausgelöst wird, wird das first click -Ereignis gelöscht. Wenn es jedoch vor dem zweiten "click" -Ereignis ausgelöst wird, wird dieses zweite Ereignis immer noch von selbst ausgelöst und Sie erhalten beides Ein Doppelklick-Ereignis wird ausgelöst und ein Einzelklick-Ereignis wird ausgelöst.

Ich sehe zwei mögliche Lösungen für dieses potenzielle Problem:

1) Legen Sie ein weiteres Zeitlimit für das Auslösen des Doppelklickereignisses fest. Markieren Sie in Ihrem Code, dass das Doppelklickereignis ausgelöst wird. Wenn dann das zweite "Einzelklick" -Ereignis ausgelöst wird, kann es diesen Status überprüfen und sagen: "oops, dbl click pending, also mache ich nichts"

2) Die zweite Option besteht darin, Ihre Zielfunktionen basierend auf Klickereignissen auszutauschen. Es könnte ungefähr so ​​aussehen:

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  var firing = false;
  var singleClick = function(){
    alert('Single');
  };

  var doubleClick = function(){ 
    alert('Double');
  };

  var firingFunc = singleClick;

  el.onclick = function() {
    // Detect the 2nd single click event, so we can stop it
    if(firing) 
      return;

    firing = true;
    timer = setTimeout(function() { 
       firingFunc(); 

       // Always revert back to singleClick firing function
       firingFunc = singleClick;
       firing = false;
    }, 150);

  }

  el.ondblclick = function() {
    firingFunc = doubleClick; 
    // Now, when the original timeout of your single click finishes, 
    // firingFunc will be pointing to your doubleClick handler        
  }
}

Grundsätzlich passiert hier, dass Sie das ursprünglich eingestellte Timeout fortsetzen. Es wird immer FiringFunc () aufgerufen. Das einzige, was sich ändert, ist, worauf firingFunc () tatsächlich zeigt. Sobald der Doppelklick erkannt wurde, wird DoubleClick festgelegt. Und dann kehren wir immer wieder zu singleClick zurück, wenn das Timeout abgelaufen ist.

Wir haben auch eine "feuernde" Variable darin, so dass wir wissen, dass das 2. Einzelklick-Ereignis abgefangen werden muss.

Eine andere Alternative besteht darin, Dblclick-Ereignisse vollständig zu ignorieren und es einfach mit den einzelnen Klicks und dem Timer zu erkennen:

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  var firing = false;
  var singleClick = function(){
    alert('Single');
  };

  var doubleClick = function(){ 
    alert('Double');
  };

  var firingFunc = singleClick;

  el.onclick = function() {
    // Detect the 2nd single click event, so we can set it to doubleClick
    if(firing){
      firingFunc = doubleClick; 
      return;
    }

    firing = true;
    timer = setTimeout(function() { 
       firingFunc(); 

       // Always revert back to singleClick firing function
       firingFunc = singleClick;
       firing = false;
    }, 150);

  }
}

Das ist nicht getestet :)

10
Matt

Einfach: 

obj.onclick=function(e){
   if(obj.timerID){
          clearTimeout(obj.timerID);
          obj.timerID=null;
          console.log("double")
         }
       else{
          obj.timerID=setTimeout(function(){
                                            obj.timerID=null;
                                            console.log("single")
                                            },250)}
}//onclick
5
Oleksandr Kyrpa
,   cellclick   :   
        function(){
            setTimeout(function(){
                if (this.dblclickchk) return;
                setTimeout(function(){
                    click event......                   
                },100);
            },500);
        }

,   celldblclick    :   
        function(){
            setTimeout(function(){
                this.dblclickchk    =   true;
                setTimeout(function(){
                                          dblclick event.....
                },100);
                setTimeout(function(){
                    this.dblclickchk = false;
                },3000);
            },1);
        }
0
iamfreenoble

Ich habe zufällig festgestellt, dass dies funktioniert (dies ist bei Bing Maps der Fall):

                 pushpin.clickTimer = -1;
                  Microsoft.Maps.Events.addHandler(pushpin, 'click', (pushpin) {
                    return function () {
                        if (pushpin.clickTimer == -1) {
                            pushpin.clickTimer = setTimeout((function (pushpin) {
                                return function () {
                                    alert('Single Clic!');
                                    pushpin.clickTimer = -1;
                                    // single click handle code here
                                }
                            }(pushpin)), 300);
                        }
                    }
                }(pushpin)));
                Microsoft.Maps.Events.addHandler(pushpin, 'dblclick', (function (pushpin) {
                    return function () {
                        alert('Double Click!');
                        clearTimeout(pushpin.clickTimer);
                        pushpin.clickTimer = -1;
                        // double click handle here
                    }
                }(pushpin)));

Es sieht so aus, als ob das Ereignis click das Ereignis dblclick maskiert, und diese Verwendung löscht es, wenn wir eine Zeitüberschreitung hinzufügen. Hoffentlich funktioniert dies nach einer geringfügigen Anpassung auch mit Fällen, die nicht von Bing Maps stammen, aber ich habe es nicht ausprobiert.

0
user2907498

Kleine fix 

       if(typeof dbtimer != "undefined"){
            dbclearTimeout(timer);
            timer = undefined;
            //double click
        }else{
            dbtimer = setTimeout(function() { 
            dbtimer = undefined;
            //single click
            }, 250);
        }
0