2012-01-04 31 views
35

Esta pregunta es similar a mi pregunta anterior, Click action on Focused DIV, pero esta vez el tema principal es Cómo evitar que se desencadene el evento de foco cuando hago clic en uno de los divs. La última vez que tuve un div con tabindex = '- 1' para hacerlo enfocable al hacer clic, ahora tengo una lista de divs con tabindex> 0 para que puedan ganar el enfoque al tabular también.Evitar disparar evento de foco al hacer clic en div

<div tabindex='1'>Div one</div> 
<div tabindex='1'>Div two</div> 
<div tabindex='1'>Div tree</div> 
<div tabindex='1'>Div four</div> 

algo más de estilo:

div { 
    height: 20px; 
    width: 60%; 
    border: solid 1px blue; 
    text-align: center; 
} 
div:focus { 
    border: solid 2px red; 
    outline: none; 
} 

Ahora estoy usando una bandera (acción) para disparar una acción (alerta) al hacer clic en el div para el segundo tiempo, y con sólo un clic si ya está enfocado, con TAB por ejemplo.

var action = false; 
$('div') 
    .click(function(e){ 
     e.stopImmediatePropagation(); 
     if(action){alert('action');} 
     action = true;}) 
    .focus(function(){action = true;}) 
    .blur(function(){action = false;}); 

El problema con el código anterior se está siendo despedido evento de foco, lo que significa stopImmediatePropagation no funciona de la manera que esperaba .. La acción de clic dos trabaja comentando la línea evento de foco, pero todavía se necesita para duplicar haga clic cuando div gana foco en TAB. Aquí está el ejemplo: http://jsfiddle.net/3MTQK/1/

Respuesta

65

DEMO aquí

creo que se echa en falta algunas partes aquí,

  1. event.stopPropagation() se utiliza para detener el evento de burbujeo. Puede leer al respecto here.

  2. event.stopImmediatePropagation() Además de evitar que se ejecuten controladores adicionales en un elemento, este método también detiene el burbujeo al llamar implícitamente al event.stopPropagation(). Puede leer al respecto here

  3. Si desea detener los eventos del navegador, entonces debe usar event.preventDefault(). Puede leer sobre él here

  4. click = mousedown + mouseup -> El foco se establecerá en un elemento HTML cuando el mouse hacia abajo sea exitoso. Entonces, en lugar de vincular el evento click, debe usar 'mousedown'. Ver mi demo

  5. No se puede usar 1 acción de valor booleano para determinar en qué div se hace clic y cuántas veces se ha hecho clic en él. Verifique mi Demo para ver cómo puede manejar eso.

+0

Si unigo dos eventos a un elemento, ¿cómo funciona eso? Por ejemplo, si escribo: $ (document) .on ("touchstart click", ".myelement", function (e) {e.stopImmediatePropagation(); // run function here}) .... Si estoy activado un dispositivo de tableta, ¿se iniciará primero el toque y se detendrá el resto de los eventos? Porque ahora si hago clic en un elemento y mantengo mi dedo presionado, tanto el inicio táctil como el clic se disparan y mi función se ejecuta dos veces. ¿StopImmediatePropagation corregirá eso? – Alex

0

Por el momento, la respuesta sería evidente para restringir su selector de la simple 'div' a un sistema de nombres de clase toggled, con lo que se podía controlar de qué elemento de su evento enfoque dispararía. Es más tedioso y requiere un poco más de codificación de excepción, pero haría el trabajo.

+0

supongo que esto funcionaría, pero la respuesta aceptada es tan mucho mejor ('event.preventDefault()' 'en el manejador de mousedown'). –

3

Para evitar simplemente disparar el foco al hacer clic en div simplemente use mousedown + event.preventDefault(). Use mousedown en lugar de hacer clic porque, como se explicó en @Selvakumar Arumugam, el foco se dispara cuando mousedown es exitoso y event.preventDefault() detiene los eventos del navegador (incluido nuestro enfoque).

Aquí está un ejemplo de código:

$('#div').on('mousedown', function(event) { 
// do your magic 
event.preventDefault(); 
}); 
Cuestiones relacionadas