2010-04-21 23 views
43

¿Hay algo que pueda hacer así (perhap a través de un plug-in)¿Hay un 'enfoque' en JavaScript (o jQuery)?

if (! $('form#contact input]').hasFocus()) { 
    $('form#contact input:first]').focus(); 
} 

Básicamente, establecer el foco en la primera entrada, pero sólo si el usuario no ha hecho clic en cualquier cosa?

Sé que esto también funcionará, pero ¿hay algo más elegante?

$(function() { 
    var focused = false; 
    $('form#contact input]').focus(function() { 
    focused = true; 
    }); 
    setTimeout(function() { 
    if (! focused) {  
     $('form#contact input:first]').focus(); 
    } 
    }, 500); 
}); 

Respuesta

62

No hay una solución nativa, pero sí hay una más elegante forma en que puede hacerlo:

jQuery.extend(jQuery.expr[':'], { 
    focus: "a == document.activeElement" 
}); 

Yo está definiendo un nuevo selector. Ver Plugins/Authoring. A continuación, puede hacer:

if ($("...").is(":focus")) { 
    ... 
} 

o:

$("input:focus").doStuff(); 
+0

Eso es genial Cletus, ¡nunca pienses en un selector personalizado! – alex

+6

Quizás deba enviar esto para versiones más recientes de jQuery, sería útil. – gnarf

+0

¿Alguna idea de por qué 'jQuery.expr' utiliza' == 'en lugar de' === '? –

7

No, no lo hay.

Sin embargo, se puede simular de esta manera:

$(':input') 
    .data('focused', false) 
    .focus(function() { $.data(this, 'focused', true); }) 
    .blur(function() { $.data(this, 'focused', false); }); 
+0

¿Por qué este downvoted? – SLaks

+0

todas las respuestas fueron excepto Vincent (haga clic en ellas). Estoy haciendo +1 de ellos para contrarrestar eso. – cletus

+0

No sé sobre los votos a favor. Tal vez lo hicieron cuando su respuesta fue solo la primera línea. De todos modos, te di un +1 :) – alex

26

$('input:focus')

Es CSS. No es necesario crear un "selector personalizado". ¡Ya existe! http://www.w3schools.com/CSS/pr_pseudo_focus.asp

Simplemente adjunte el proceso que desee hacer a ese selector, y lo eliminará si el elemento en cuestión no está enfocado. Hice esto recientemente para mantener un keyup instanciando una comprobación de error de entrada de correo electrónico cuando la entrada de correo electrónico no se estaba utilizando.

Si todo lo que estamos tratando de hacer es comprobar si el usuario se ha centrado en sí mismos nada, sólo hacer esto:

if($('input:focus').size() == 0){ 
    /* Perform your function! */ 
} 
+1

Usted está equivocado. jQuery, a diferencia de CSS, no tiene los selectores ': focus' o': hover'. – SLaks

+2

Parece que sí: http://jsfiddle.net/vnYCK/ – Matt

+1

jQuery utiliza selectores de CSS. Si funciona en CSS, funciona en jQ. Créeme. Si tiene alguna duda, pruebe el formulario en esta página y luego inspeccione el JS: http://www.ddrewdesign.com/contact/ El código de activación está en la línea 124. Sin embargo, no he intentado ': hover' antes, entonces No puedo hablar por eso. El truco está en hacer que el JS haga el trabajo preliminar para que pueda verificarlo, por lo que debes ponerlo dentro de una acción de algún tipo. – dclowd9901

9

tuve problemas con el enfoque Cletus, usando jQuery 1.3.2 y Firefox 3.6. 8, porque la cadena "a == document.activeElement" no era una función válida.

Lo arreglé definiendo una función para la clave focus. De hecho, todas las demás teclas definidas en jQuery.expr[':'] se definen como funciones. Aquí está el código:

jQuery.extend(jQuery.expr[':'], { 
    focus: function(e){ return e == document.activeElement; } 
}); 

Por lo tanto, ahora funciona como se esperaba.

Sin embargo, estaba experimentando un comportamiento extraño en Firefox 3.6.8 (¿quizás un error en FF?). Si hacía clic en un texto de entrada mientras se procesaba la página, y si llamaba al is(":focus") en la carga de la página, obtenía un error del navegador, reportado por FireBug, y el script se rompía.

Para solucionar esto, rodeé el código con un bloque try...catch, devolviendo false en caso de error.Úselo si desea evitar que sus usuarios experimenten el mismo error:

jQuery.extend(jQuery.expr[':'], { 
    focus: function(e){ 
     try{ return e == document.activeElement; } 
     catch(err){ return false; } 
    } 
}); 
1

Aquí hay una forma concisa de hacerlo.

$(document.activeElement) 

o para conectarlo a su ejemplo ..

if ($('form#contact input]')!=$(document.activeElement)) { ... } 
+0

El de abajo nunca funcionará ya que siempre serán colecciones de jQuery diferentes. – alex

11

jQuery 1.6 ahora tiene un selector dedicado :focus.

2

Sé que esto es una cuestión de edad, pero puede ser mi solución ayudará a alguien :)

ya que esto aún no ha trabajado para mí:

if ($(this)!=$(document.activeElement)) { ... } 

..were "este" se devuelve desde el desenfoque función. Así lo hice:

if ($(document.activeElement).attr("class") != "input_textbox"){ ... } 
+0

La primera solución se guarda en colecciones jQuery sin ningún motivo, y también fallará ya que serán los diferentes objetos. La segunda rara vez es una buena forma de comprobar si un elemento es el que coincide con algo, ya que los elementos pueden tener múltiples clases. – alex

-2
$('*:focus') 

(Necro ftw, pero sigue siendo válida y útil)

+0

El '*' no debería ser requerido. – alex

+0

Necroing está bien, las preguntas y respuestas son intemporales, e incluso hay un par de insignias para responder a una pregunta mucho más tarde con un buen puntaje, como Necromancer. _Sin embargo, _ estoy bajando esto porque no proporciona ninguna guía sobre cómo verificar si elementos específicos tienen enfoque. ¿Eres capaz de agregar eso? – doppelgreener

3

frustrante difícil encontrar una solución a este problema teniendo en cuenta que la solución es realmente muy simple:

if (document.activeElement == this) { 
 
    // has focus 
 
} 
 

 
if (document.activeElement != this) { 
 
    // does not have focus 
 
}

+0

Gracias por proporcionar una solución JS nativa. – JoshJ

Cuestiones relacionadas