2012-05-18 12 views
11

Tengo un pequeño problema con el evento de enfoque que acabo de conocer. Aparentemente, el foco se dispara al cambiar a otra pestaña del navegador y luego nuevamente. Prefiero que eso no suceda; ¿Es posible?Al cambiar las pestañas del navegador se desata indeciblemente el evento de enfoque, especialmente en Google Chrome

Nunca me había dado cuenta de esto hasta hoy. He aquí una pequeña demostración: http://jsfiddle.net/MJ6qb/1/

var times = 0; 
$('input').on('focus', function() { 
    times ++; 
    $(this).after('<br>Focused '+times+' times'); 
}); 

para reproducir: Enfoque en la entrada, a continuación, cambiar las pestañas del navegador, a continuación, cambiar de nuevo. Todos los navegadores parecen disparar el evento de enfoque cuando vuelves a la pestaña, y Google Chrome 19 lo está disparando dos veces!

Idealmente, la función no debe funcionar al cambiar las pestañas del navegador en absoluto, pero sólo el usuario hace clic o Tab, pero ahora que soy consciente del problema Chrome que estoy un poco más preocupado por eso porque es resultante en solicitudes AJAX consecutivas no deseadas en mi aplicación real (es para buscar resultados para un autocompletado que debe estar actualizado, pero no tanto como para utilizar el evento de teclado).

No parece jQuery relacionado (lo probé con vainilla javascript) pero puedo usar jQuery para una solución. ¿Hay algo que pueda hacer al respecto? Sé que puedo usar jQuery's one(), pero quiero que la función se ejecute más de una vez.

+1

Ligeramente relación, pero que podría ser capaz de detectar cuando la pestaña del navegador está enfocada o borrosa y ove anula el comportamiento predeterminado como en [this] (http://stackoverflow.com/a/6184276/1028949). El doble disparo de Chrome es un [error conocido] (http://code.google.com/p/chromium/issues/detail?id=124583), por lo que puedo decir. – Quantastical

+0

Ah, gracias por eso, no me di cuenta de que era un error conocido, solo lo encontré mientras probaba el código en Chrome justo antes de publicarlo para asegurarme de que no era algo de FF (que desarrollé). Tengo ganas de darme por vencido y "dejarlo montar", pero es realmente molesto. Veré si puedo hacer algo con el código en esa respuesta. –

+1

Se espera el comportamiento que está experimentando. Cuando sales de la pestaña, estás desenfocando ese cuadro de texto y cuando regresas lo estás enfocando de nuevo. Lo mismo ocurre con ir a otra aplicación. Lamentablemente, no puedo pensar en una forma de anular o evitar esto. – Quantastical

Respuesta

5

Trate this

var times = 0; 
var prevActiveElement; 

    $(window).on("blur", function(e){ 
      prevActiveElement = document.activeElement; 
    }); 

    $('input').on('focus', function() { 
     if (document.activeElement === prevActiveElement) { 
      return; 
     } 
     prevActiveElement = document.activeElement; 
     times++; 
     $(this).after('<br>Focused ' + times + ' times'); 
    }).on("blur", function(){ 
     prevActiveElement = null; 
    });​ 
+0

¡Parece que esto funciona! Gracias por la solución! Además, nunca se supo acerca de 'activeElement', así que doy las gracias por esa información. –

+0

Por cierto, esto también funciona perfectamente en producción con múltiples entradas: http://jsfiddle.net/MJ6qb/5/ (si tiene curiosidad, abra la consola para ver las solicitudes). –

+0

@WesleyMurch el '$ (" cuerpo "). On (" desenfoque ")' no se activa en absoluto. 'Blur' no burbujea, es probable que desee' $ ("body"). On ("focusout", "[data-autocomplete]", fn) '. El equivalente para el enfoque es '$ (" cuerpo "). On (" focusin "," [data-autocomplete] ", fn)' – Esailija

3

Pruebe lo siguiente para evitar el problema:

var times = 0, foc=true; 

$(window).on('focus', function() { 
    foc = false; 
    setTimeout(function() {foc=true}, 200); 
}); 

$('input').on('focus', function() { 
    if (foc || times===0) { 
     times ++; 
     $(this).after('<br>Focused '+times+' times'); 
    } 
}); 

FIDDLE

+0

Hasta el momento, no se activa al hacer clic, a menos que primero se enfoque con otro método, como TAB (o haga clic primero en otra entrada), todavía en prueba. ¡Pero sí, solución interesante! –

+0

Eso es extraño, parece funcionar bien aquí en Chrome, el evento de foco se dispara siempre, pero no en los cambios de la pestaña del navegador. – adeneo

+0

Simplemente no parece funcionar si hace clic en la entrada antes de hacer cualquier otra cosa. @adeno ¿Lo intentaste? –

Cuestiones relacionadas