2009-10-09 11 views
21

Mam element na mojej stronie, który muszę dołączyć do obsługi zdarzeń onclick i ondblclick. Kiedy wydarzy się jedno kliknięcie, powinno to zrobić coś innego niż dwukrotne kliknięcie. Kiedy po raz pierwszy zacząłem wykonywać tę pracę, moja głowa zaczęła wirować. Oczywiście, onclick zawsze będzie uruchamiany po dwukrotnym kliknięciu. Więc próbowałem za pomocą struktury limitu czasu oparte tak ...Jak używać zarówno onclick, jak i ondblclick dla elementu?

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

Ale mam niespójnych wyników (używając IE8). To działałoby poprawnie wiele razy, ale czasami dostałbym alert "Pojedynczy" dwa razy.

Czy ktoś już to zrobił? Czy istnieje skuteczniejszy sposób?

+0

Po otrzymaniu powiadomienia pojedyncze kliknięcia, jest to zawsze dwójkami, czy też czasami tylko jeden alert? – Matt

+0

Czasami mam tylko jeden. –

Odpowiedz

19

Podobnie jak Matt, miałem o wiele lepsze doświadczenie kiedy nieznacznie zwiększyłem wartość limitu czasu. Ponadto, aby złagodzić problem jednego kliknięcia wypalania dwukrotnie (który nie był w stanie odtworzyć z wyższym zegarem tak), dodałem linię do jednego kliknięcia Handler:

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

ten sposób, jeśli kliknięcie jest już ustawiony do ognia, oczyści się, aby uniknąć duplikatów "pojedynczych" alarmów.

+4

Wow, uwielbiam prostotę twojej odpowiedzi. Sądzę, że możesz upuścić dblclick listener razem i zastąpić twój blok IF na: {clearTimeout (timer); myDoubleClickHandler(); powrót; } – Matt

10

Jeśli otrzymujesz 2 alerty, wydaje się, że Twój próg wykrycia podwójnego kliknięcia jest zbyt mały. Spróbuj zwiększyć 150 do 300ms.

Ponadto - nie jestem pewien, czy masz gwarancję zamówienia, w którym są uruchamiane kliknięcia i dblclick. Tak więc, gdy Twój dblclick zostanie zwolniony, usuwa jedno kliknięcie, ale jeśli wystrzeli przed drugim wydarzeniem "kliknięcia", to drugie wydarzenie będzie nadal strzelać samodzielnie, a skończysz z podwójnym kliknięciem. Wypalanie zdarzeń po kliknięciu i wypalanie zdarzeń jednym kliknięciem.

Widzę dwa możliwe rozwiązania tego potencjalnego problemu:

1) Ustaw limit czasu dla innej rzeczywistości wypalania kliknij dwukrotnie zdarzenie. Zaznacz w swoim kodzie, że zdarzenie o podwójnym kliknięciu wkrótce się uruchomi. Wtedy, gdy 2nd „jednym kliknięciem” Zdarzenie, może sprawdzić na tym stanie, i powiedzieć „ups, dbl kliknij w toku, więc będę robić nic”

2) Druga opcja to zamienić funkcje docelowe obecnie na podstawie zdarzeń kliknięcia. Może to wyglądać mniej więcej tak:

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

Zasadniczo, to co się tutaj dzieje, pozwala ci ustawić pierwotny ustawiony limit czasu. Zawsze będzie wywoływać metodę firingFunc(); Jedyną rzeczą, która się zmienia, jest to, na co faktycznie wskazuje element wywoływania firingFunc(). Po wykryciu podwójnego kliknięcia ustawia go na doubleClick. A potem zawsze wracamy do singla po przekroczeniu limitu czasu.

Mamy również zmienną "wypalania", więc wiemy, że przechwycimy drugie zdarzenie z pojedynczym kliknięciem.

Inną alternatywą jest ignorowanie dblclick wydarzenia całkowicie i po prostu go wykryć z pojedynczych kliknięć i timer:

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

    } 
} 

To jest niesprawdzone :)

+0

Pierwszy przykład kodu pracował dla mnie, ale wpadł na problemy z drugim. – donohoe

2

Proste:

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 
0

Mała poprawka

 if(typeof dbtimer != "undefined"){ 
      dbclearTimeout(timer); 
      timer = undefined; 
      //double click 
     }else{ 
      dbtimer = setTimeout(function() { 
      dbtimer = undefined; 
      //single click 
      }, 250); 
     } 
0
, 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); 
     } 
+1

Nie jest jasne, jak to odpowiada na pytanie. Dobra odpowiedź powinna również wyjaśnić kod. Biorąc pod uwagę, że jest to obiekt i zaczyna się od przecinka, trudno jest przewidzieć, co należy z tym zrobić. – iblamefish

Powiązane problemy