javascript - remove - jquery unfocus
Usando jQuery para probar si una entrada tiene enfoque (15)
En la página principal de un sitio que estoy construyendo, varios <div>
usan la pseudo-clase CSS :hover
para agregar un borde cuando el mouse está sobre ellos. Uno de los <div>
s contiene un <form>
que, utilizando jQuery, mantendrá el borde si una entrada dentro de él tiene el foco. Esto funciona perfectamente, excepto que IE6 no es compatible con :hover
sobre cualquier elemento distinto de <a>
s. Entonces, solo para este navegador estamos usando jQuery para imitar CSS :hover
usando el método $(#element).hover()
. El único problema es que ahora que jQuery maneja tanto el focus()
formulario focus()
como el de desplazamiento hover()
, cuando una entrada tiene el enfoque, el usuario mueve el mouse hacia adentro y hacia afuera, el borde desaparece.
Estaba pensando que podríamos usar algún tipo de condicional para detener este comportamiento. Por ejemplo, si probamos con el mouse fuera si alguna de las entradas tenía el foco, podríamos evitar que el borde se vaya. AFAIK, no hay un selector de :focus
en jQuery, así que no estoy seguro de cómo hacer que esto suceda. ¿Algunas ideas?
Actualización de Abril 2015
Dado que esta pregunta ha existido por un tiempo, y algunas convenciones nuevas han entrado en juego, creo que debería mencionar que el método de vida se ha depreciado.
En su lugar, el método .on
ahora ha sido introducido.
Su documentation es muy útil para explicar cómo funciona;
El método .on () asocia controladores de eventos al conjunto de elementos actualmente seleccionado en el objeto jQuery. A partir de jQuery 1.7, el método .on () proporciona toda la funcionalidad necesaria para adjuntar controladores de eventos. Para obtener ayuda sobre la conversión de métodos de eventos jQuery más antiguos, consulte .bind (), .delegate () y .live ().
Por lo tanto, para que tenga como objetivo el evento ''entrada enfocada'', puede usar esto en un script. Algo como:
$(''input'').on("focus", function(){
//do some stuff
});
Esto es bastante robusto e incluso te permite usar la tecla TAB también.
jQuery 1.6+
jQuery agregó un :focus
selector de :focus
, por lo que ya no necesitamos agregarlo nosotros mismos. Simplemente use $("..").is(":focus")
jQuery 1.5 y por debajo
Edit: A medida que los tiempos cambian, encontramos mejores métodos para probar el enfoque, el nuevo favorito es esta idea de Ben Alman :
jQuery.expr['':''].focus = function( elem ) {
return elem === document.activeElement && ( elem.type || elem.href );
};
Citado de Mathias Bynens here :
Tenga en cuenta que la
(elem.type || elem.href)
se agregó para filtrar falsos positivos como body. De esta manera, nos aseguramos de filtrar todos los elementos excepto los controles de formulario y los hipervínculos.
Estás definiendo un nuevo selector. Ver Plugins/Authoring . Entonces puedes hacer:
if ($("...").is(":focus")) {
...
}
o:
$("input:focus").doStuff();
Cualquier jQuery
Si solo quieres descubrir qué elemento tiene el foco, puedes usar
$(document.activeElement)
Si no está seguro de si la versión será 1.6 o inferior, puede agregar el :focus
selector de :focus
si falta:
(function ( $ ) {
var filters = $.expr[":"];
if ( !filters.focus ) {
filters.focus = function( elem ) {
return elem === document.activeElement && ( elem.type || elem.href );
};
}
})( jQuery );
¿Has pensado en usar mouseOver y mouseOut para simular esto? También mira en mouseEnter y mouseLeave
Aquí hay una respuesta más robusta que la aceptada actualmente:
jQuery.expr['':''].focus = function(elem) {
return elem === document.activeElement && (elem.type || elem.href);
};
Tenga en cuenta que la (elem.type || elem.href)
se agregó para filtrar falsos positivos como body
. De esta manera, nos aseguramos de filtrar todos los elementos excepto los controles de formulario y los hipervínculos.
(Tomado de esta esencia por Ben Alman .)
CSS:
.focus {
border-color:red;
}
JQuery:
$(document).ready(function() {
$(''input'').blur(function() {
$(''input'').removeClass("focus");
})
.focus(function() {
$(this).addClass("focus")
});
});
Hay un complemento para verificar si un elemento está enfocado: http://plugins.jquery.com/project/focused
$(''input'').each(function(){
if ($(this) == $.focused()) {
$(this).addClass(''focused'');
}
})
Lo que terminé haciendo es crear una clase arbitraria llamada .elementhasfocus, que se agrega y elimina dentro de la función jQuery focus (). Cuando la función hover () se ejecuta con el mouse hacia fuera, comprueba si hay .elementhasfocus:
if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border");
Por lo tanto, si no tiene esa clase (lea: no hay elementos dentro del div), se eliminará el borde. De lo contrario, no pasa nada.
Mantenga un registro de ambos estados (desplazado, enfocado) como indicadores de verdadero / falso, y siempre que uno cambie, ejecute una función que elimine el borde si ambos son falsos; de lo contrario, muestra el borde.
Entonces: onfocus sets focus = true, onblur sets focus = false. Los conjuntos onmouseover hovered = true, los conjuntos onmouseout hovered = false. Después de que cada uno de estos eventos ejecute una función que agrega / elimina un borde.
No estoy completamente seguro de lo que está buscando, pero parece que esto puede lograrse almacenando el estado de los elementos de entrada (o el div?) Como una variable:
$(''div'').each(function(){
var childInputHasFocus = false;
$(this).hover(function(){
if (childInputHasFocus) {
// do something
} else { }
}, function() {
if (childInputHasFocus) {
// do something
} else { }
});
$(''input'', this)
.focus(function(){
childInputHasFocus = true;
})
.blur(function(){
childInputHasFocus = false;
});
});
No hay: foco, pero hay: seleccionado http://docs.jquery.com/Selectors/selected
pero si desea cambiar el aspecto de las cosas en función de lo que esté seleccionado, probablemente debería estar trabajando con los eventos de desenfoque.
Que yo sepa, no puede preguntar al navegador si alguna entrada en la pantalla tiene un enfoque, tiene que configurar algún tipo de seguimiento de enfoque.
Por lo general, tengo una variable llamada "noFocus" y la configuro como verdadera. Luego agrego un evento de enfoque a todas las entradas que hace que noFocus sea falso. Luego agrego un evento de desenfoque a todas las entradas que configuran noFocus en verdadero.
Tengo una clase de MooTools que maneja esto con bastante facilidad, estoy seguro de que podría crear un complemento jQuery para hacer lo mismo.
Una vez que se haya creado, puede hacer clic en noFocus antes de hacer cualquier cambio de borde.
Sencillo
<input type="text" />
<script>
$("input").focusin(function() {
alert("I am in Focus");
});
</script>
Tuve un evento .live ("focus") configurado para seleccionar () (resaltar) el contenido de una entrada de texto para que el usuario no tuviera que seleccionarlo antes de escribir un nuevo valor.
$ (formObj) .select ();
Debido a las peculiaridades entre los diferentes navegadores, la selección a veces sería reemplazada por el clic que la causó, y deseleccionaría el contenido justo después para colocar el cursor dentro del campo de texto (funcionó principalmente bien en FF pero falló en IE)
Pensé que podría resolver esto poniendo un ligero retraso en la selección ...
setTimeout (function () {$ (formObj) .select ();}, 200);
Esto funcionó bien y la selección persistiría, pero surgió un problema extraño. Si pasaba de un campo a otro, el enfoque cambiaría al siguiente campo antes de que se realizara la selección. Dado que seleccionar el enfoque de robos, el enfoque volverá y activará un nuevo evento de "enfoque". Esto terminó en una cascada de entradas de selección de baile en toda la pantalla.
Una solución viable sería verificar que el campo aún tiene enfoque antes de ejecutar select (), pero como se mencionó, no hay una forma simple de verificar ... Terminé simplemente prescindiendo de todo el resaltado automático, en lugar de girar lo que debería ser una sola llamada jQuery select () a una función enorme cargada de subrutinas ...
Una alternativa al uso de clases para marcar el estado de un elemento es la funcionalidad interna del almacén de datos .
PD: puede almacenar valores booleanos y lo que desee con la función data()
. No se trata solo de cuerdas :)
$("...").mouseover(function ()
{
// store state on element
}).mouseout(function ()
{
// remove stored state on element
});
Y luego solo es cuestión de acceder al estado de los elementos.
si a alguien le importa, hay una manera mucho mejor de capturar el foco ahora, $(foo).focus(...)