¿Cómo establezco el foco en el primer elemento de entrada en un formulario HTML independiente de la identificación?

84

¿Existe una forma sencilla de establecer el foco (cursor de entrada) de una página web en el primer elemento de entrada (cuadro de texto, lista desplegable, ...) al cargar la página sin tener que saber la identificación del elemento?

Me gustaría implementarlo como un script común para todas mis páginas / formularios de mi aplicación web.

splattne
fuente
7
OBSERVACIÓN si el formulario se coloca hacia abajo en la página de una manera que el usuario tiene que desplazarse hacia abajo para ver el formulario, al establecer el enfoque, se desplazará automáticamente hacia abajo en la página como lo haría un ancla. Esto no es muy bueno porque el usuario que acceda a dicha página la verá inmediatamente desplazada hacia abajo hasta la posición del formulario. Probé en Safari y FF (IE7 no realiza el desplazamiento de página).
Marco Demaio
@Marco_Demaio Mi aplicación web está estructurada de manera que cada página tiene sus cuadros de entrada cerca de la parte superior de la ventana.
Splattne
3
¿Qué pasa si el usuario cambia el tamaño de la altura de la ventana del navegador a algo más pequeño que 768px? La página se desplazaría hasta donde estableció el enfoque. De todos modos solo quería advertirte en caso de que no supieras sobre un problema tan menor, yo tampoco lo sabía antes de hacer algunas pruebas.
Marco Demaio

Respuestas:

96

También puede probar el método basado en jQuery:

$(document).ready(function() {
    $('form:first *:input[type!=hidden]:first').focus();
});
Marko Dumic
fuente
¡Funciona! Estoy empezando a integrar jQuery en mi aplicación web. Entonces, creo que seguiré con este enfoque. ¡Muchas gracias, Marko!
splattne
3
¿Qué sucede si el primer formulario de la página está oculto en este caso? ¿O si el primer elemento del formulario está oculto a través de CSS? Seguramente esto fallaría. Estoy siendo pedante, por supuesto, pero así es como lo hago.
James Hughes
En mi caso (usando ASP.NET) tengo solo UN formulario que nunca está oculto. Entonces esto funciona para mí.
splattne
@Jame Hughes, puedes escribirlo como una función y llamarlo cuando lo necesites, y puedes hacer excepciones. Para mí, esta solución realmente ayudó.
Luci
esto no me funciona por alguna razón. ¿No debería ver un cursor?
Chris
136

Aunque esto no responde a la pregunta (requiere un script común), creo que podría ser útil para otros saber que HTML5 presenta el atributo 'autofocus'

<form>
  <input type="text" name="username" autofocus>
  <input type="password" name="password">
  <input type="submit" value="Login">
</form>

Sumérjase en HTML5 tiene más información.

Jacob Stanley
fuente
2
autofocus es el nombre del atributo. ¿Qué pasa con su valor? ¿Algo como autofocus = true no es necesario? ¿Qué significa no establecer ningún valor?
Geek
4
En HTML5, algunos atributos no necesitan tener un valor, "marcado" es otro atributo cuando este es el caso. Creo que cuando se deja el valor, se da a entender que es el mismo que el nombre (por ejemplo, autofocus = "autofocus" y check = "check").
Jacob Stanley
Mi aplicación Spring se rompe cuando intento usarla autofocussin valor spring:form. autofocus="autofocus"aunque funciona bien. Gracias, @Jacob.
Sergei Tachenov
2
@Geek El atributo de enfoque automático, como muchos otros, es un tipo de atributo booleano. Es por eso que se usa solo de manera declarativa, no asignándole un valor. Ver más detalles en las especificaciones de w3c: w3.org/TR/html5/infrastructure.html#boolean-attribute
n1kkou
34
document.forms[0].elements[0].focus();

Esto se puede refinar utilizando un bucle para, por ejemplo. no enfocar ciertos tipos de campo, campos deshabilitados, etc. Mejor puede ser agregar una clase = "enfoque automático" para el campo que en realidad no se centró falta, y un bucle sobre las formas [i] .elements [j] en busca de ese className.

De todos modos: normalmente no es una buena idea hacer esto en todas las páginas. Cuando enfoca una entrada, el usuario pierde la capacidad de, por ejemplo. desplazarse por la página desde el teclado. Si es inesperado, esto puede ser molesto, así que solo enfoque automáticamente cuando esté bastante seguro de que usar el campo del formulario será lo que el usuario quiere hacer. es decir. si eres Google.

bobince
fuente
3
Debería ser la respuesta correcta, porque la pregunta no tiene etiqueta jquery.
Kalle H. Väravas
@ KalleH.Väravas no, debería ser rechazado porque hace suposiciones que no se encuentran en ninguna parte en cuestión, por ejemplo. hay al menos una forma. Generalmente, no funciona.
9ilsdx 9rvj 0lo
18

La expresión jQuery más completa que encontré funcionando es (a través de la ayuda de aquí )

$(document).ready(function() {
    $('input:visible:enabled:first').focus();
});
ngeek
fuente
1
Estaba usando esto, noté que se ejecuta extremadamente lento en IE cuando tiene un gran número> 1000 de casillas de verificación en una tabla. No estoy seguro de qué hacer al respecto, es posible que tenga que renunciar a enfocar el primer campo de entrada.
Sam Watkins
7

Si está utilizando el marco Prototype JavaScript, puede utilizar el método focusFirstElement :

Form.focusFirstElement(document.forms[0]);
John Topley
fuente
5

También debe omitir las entradas ocultas.

for (var i = 0; document.forms[0].elements[i].type == 'hidden'; i++);
document.forms[0].elements[i].focus();
Marko Dumic
fuente
Puede que me equivoque, pero este bucle no tiene un comportamiento definido si los formularios [0] no tienen entradas ocultas.
xtofl
Exactamente. Se utiliza para omitir las entradas ocultas principales. Y está escrito asumiendo que hay campos no ocultos en el formulario. También podría haberlo hecho con jQuery (publicaré otra respuesta) pero no mencionaste que quieres que jQuery esté involucrado.
Marko Dumic
1
@MarkoDumic ¿Por qué desperdiciar memoria si puede usar una whiledeclaración?
Lucio
3

Al colocar este código al final de su bodyetiqueta, se enfocará el primer elemento habilitado visible, no oculto en la pantalla automáticamente. Manejará la mayoría de los casos que se me ocurran con poca antelación.

<script>
    (function(){
        var forms = document.forms || [];
        for(var i = 0; i < forms.length; i++){
            for(var j = 0; j < forms[i].length; j++){
                if(!forms[i][j].readonly != undefined && forms[i][j].type != "hidden" && forms[i][j].disabled != true && forms[i][j].style.display != 'none'){
                    forms[i][j].focus();
                    return;
                }
            }
        }
    })();
</script>
James Hughes
fuente
1
Una cosa a considerar aquí es que puede coincidir con elementos que no están ocultos en sí mismos, pero un ancestro sí. Eso requeriría rastrear el DOM y probar la visibilidad de cada ancestro, lo que creo que es una exageración para este tipo de situación.
James Hughes
¿Qué pasa con <input type = "text" readonly = "readonly">? Creo que debería agregar tal caso a su código. Normalmente, la gente no quiere centrarse en un campo de texto de entrada de solo lectura. De todos modos buen código y +1 gracias!
Marco Demaio
Sin probar pero lo actualicé con! Formularios [i] [j] .readonly! = Undefined
James Hughes
3

Estoy usando esto:

$("form:first *:input,select,textarea").filter(":not([readonly='readonly']):not([disabled='disabled']):not([type='hidden'])").first().focus();
Robert Brooker
fuente
2

Esto obtiene la primera entrada común visible, incluidas las áreas de texto y los cuadros de selección. Esto también asegura que no estén ocultos, deshabilitados o de solo lectura. también permite un div de destino, que utilizo en mi software (es decir, la primera entrada dentro de este formulario).

$("input:visible:enabled:not([readonly]),textarea:visible:enabled:not([readonly]),select:visible:enabled:not([readonly])", 
    target).first().focus();
Dave K
fuente
1

Para aquellos que usan JSF2.2 + y no pueden pasar el enfoque automático como un atributo sin valor, use esto:

 p:autofocus="true"

Y agréguelo al espacio de nombres p (también se usa a menudo pt. Lo que quiera).

<html ... xmlns:p="http://java.sun.com/jsf/passthrough">
feder
fuente
0

Con AngularJS:

angular.element('#Element')[0].focus();
EpokK
fuente
0

Esto incluye áreas de texto y excluye botones de opción.

$(document).ready(function() {
    var first_input = $('input[type=text]:visible:enabled:first, textarea:visible:enabled:first')[0];
    if(first_input != undefined){ first_input.focus(); }
});
Héctor Pérez
fuente
0

Debería poder usar clientHeight en lugar de verificar el atributo de visualización, ya que un padre podría estar ocultando este elemento:

function setFocus() {
    var forms = document.forms || [];
        for (var i = 0; i < forms.length; i++) {
            for (var j = 0; j < forms[i].length; j++) {
            var widget = forms[i][j];
                if ((widget && widget.domNode && widget.domNode.clientHeight > 0) && typeof widget.focus === "function")
                 && (typeof widget.disabled === "undefined" || widget.disabled === false)
                 && (typeof widget.readOnly === "undefined" || widget.readOnly === false)) {
                        widget.focus();
                        break;
                }
            }
        }
    }   
}
thecoolmacdude
fuente
0

Sin bibliotecas de terceros, use algo como

  const inputElements = parentElement.getElementsByTagName('input')
  if (inputChilds.length > 0) {
    inputChilds.item(0).focus();
  }

Asegúrese de considerar todas las etiquetas de los elementos del formulario, descarte las ocultas / deshabilitadas como en otras respuestas, etc.

cghislai
fuente
0

sin jquery, por ejemplo, con javascript regular:

document.querySelector('form input:not([type=hidden])').focus()

funciona en Safari pero no en Chrome 75 (abril de 2019)

localhostdotdev
fuente