2009-10-09 218 views
21

Tengo un elemento en mi página al que debo adjuntar los controladores de eventos clickclick y ondblclick. Cuando ocurre un solo clic, debe hacer algo diferente a un doble clic. Cuando comencé a tratar de hacer que esto funcionara, mi cabeza comenzó a dar vueltas. Obviamente, onclick siempre se activará cuando haga doble clic. Así que he intentado utilizar una estructura basada en el tiempo de espera como esta ...¿Cómo usar onclick y ondblclick en un elemento?

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

Pero tengo resultados inconsistentes (usando IE8). Funcionaría correctamente muchas veces, pero a veces recibiría la alerta "Individual" dos veces.

¿Alguien ha hecho esto antes? ¿Hay una manera más efectiva?

+0

cuando obtiene sus alertas en Una, es siempre de dos en dos, o usted consigue a veces sólo una alerta? – Matt

+0

A veces solo obtengo uno. –

Respuesta

19

como Matt, que tenía una experiencia mucho mejor cuando incremente ligeramente el valor de tiempo de espera. Además, para mitigar el problema de un solo clic de tiro dos veces (que yo era incapaz de reproducir con el temporizador más alta de todos modos), he añadido una línea al único controlador de clic:

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

esta manera, si clic ya está establecido para disparar, se borrará para evitar alertas "únicas" duplicadas.

+4

Guau, me encanta la simplicidad de tu respuesta. Supongo que puedes soltar el oyente dblclick y reemplazar tu bloque IF por: {clearTimeout (timer); myDoubleClickHandler(); regreso; } – Matt

10

Si obtiene 2 alertas, parece que su umbral para detectar un doble clic es demasiado pequeño. Intenta aumentar de 150 a 300 ms.

Además, no estoy seguro de que tenga garantizado el orden en el que se activan los clics y los clics. Por lo tanto, cuando se apaga su doble clic, borra el primer clic en el evento, pero si se dispara antes del segundo evento de "clic", este segundo evento se disparará solo, y usted terminará con un doble haga clic en activación de evento y activación de evento de un solo clic.

veo dos soluciones posibles a este problema potencial:

1) juego otro tiempo de espera para llegar a disparar el evento de doble clic. Marque en su código que el evento de doble clic está a punto de disparar. Luego, cuando se activa el segundo evento de 'solo clic', puede verificar este estado y decir "oops, dbl haga clic en pendiente, así que no haré nada"

2) La segunda opción es intercambiar las funciones de destino basado en eventos de clic. Puede ser algo como esto:

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

Básicamente lo que está sucediendo aquí es que dejes que el tiempo de espera original que establezcas continúe. Siempre llamará a dispararFunc(); Lo único que cambia es a lo que apuntaba en realidad el disparo de Func(). Una vez que se detecta el doble clic, lo establece en doubleClick. Y luego siempre volvemos a SingleClick una vez que expira el tiempo de espera.

También tenemos una variable de "disparo" allí, así que sabemos interceptar el segundo evento de un solo clic.

Otra alternativa es ignorar eventos DblClick del todo, y justo detectarlo con los clics individuales y el temporizador:

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

    } 
} 

Esto no se ha probado :)

+0

El primer ejemplo de código funcionó pero tuve problemas con el segundo. – donohoe

2

simple:

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

pequeño arreglo

 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

No está claro cómo responde esto a la pregunta. Una buena respuesta debería proporcionar alguna explicación del código también. Dado que se trata de un objeto y comienza con una coma, es difícil ver qué se debe hacer con esto. – iblamefish

Cuestiones relacionadas