Comment définir le focus sur le premier élément d'entrée dans un formulaire HTML indépendant de l'ID?


84

Existe-t-il un moyen simple de définir le focus (curseur de saisie) d'une page Web sur le premier élément d'entrée (zone de texte, liste déroulante, ...) lors du chargement de la page sans avoir à connaître l'id de l'élément?

Je voudrais l'implémenter comme un script commun pour toutes mes pages / formulaires de mon application Web.


7
REMARQUE si le formulaire est placé vers le bas dans la page d'une manière que l'utilisateur doit faire défiler la page vers le bas pour voir le formulaire, en définissant le focus fera automatiquement défiler la page vers le bas comme le ferait une ancre. Ce n'est pas très bon car l'utilisateur accédant à une telle page la verrait immédiatement défiler jusqu'à la position du formulaire. J'ai testé sur Safari et FF (IE7 n'effectue pas le défilement de page).
Marco Demaio

@Marco_Demaio Mon application Web est structurée de manière à ce que chaque page ait ses zones de saisie en haut de la fenêtre.
splattne

3
et si l'utilisateur redimensionnait la hauteur de la fenêtre du navigateur à quelque chose de plus petit que 768px. La page défile jusqu'à l'endroit où vous définissez le focus. Quoi qu'il en soit, je voulais seulement vous avertir au cas où vous ne saviez pas ce problème mineur, je ne savais pas non plus avant de faire quelques tests.
Marco Demaio

Réponses:


96

Vous pouvez également essayer la méthode basée sur jQuery:

$(document).ready(function() {
    $('form:first *:input[type!=hidden]:first').focus();
});

Ça marche! Je commence à intégrer jQuery dans mon application Web. Donc, je pense que je vais m'en tenir à cette approche! Merci beaucoup, Marko!
splattne

3
Que se passe-t-il si le premier formulaire de la page est masqué dans ce cas? Ou si le premier élément du formulaire est masqué via CSS? Cela échouerait sûrement. Je suis pédant bien sûr mais c'est comme ça que je roule.
James Hughes

Dans mon cas (en utilisant ASP.NET), je n'ai qu'un seul formulaire qui n'est jamais caché. Donc cela fonctionne pour moi.
splattne

@Jame Hughes, vous pouvez l'écrire en tant que fonction et l'appeler quand vous en avez besoin, et vous pouvez faire des exceptions. Pour moi, cette solution a vraiment aidé.
Luci

cela ne fonctionne pas pour moi pour une raison quelconque. ne devrais-je pas voir un curseur.
Chris

136

Bien que cela ne réponde pas à la question (nécessitant un script commun), je pensais qu'il pourrait être utile pour d'autres de savoir que HTML5 introduit l'attribut 'autofocus':

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

Plongez dans HTML5 pour plus d'informations.


2
l'autofocus est le nom d'attribut. Qu'en est-il de sa valeur? Quelque chose comme l'autofocus = vrai pas nécessaire? Que signifie ne pas définir de valeur?
Geek

4
En HTML5, certains attributs n'ont pas besoin d'avoir une valeur, «vérifié» est un autre attribut où c'est le cas. Je crois que lorsque la valeur est laissée de côté, il est sous-entendu que c'est le même que le nom (par exemple, autofocus = "autofocus" et vérifié = "vérifié").
Jacob Stanley

Mon application Spring est interrompue lorsque j'essaie d'utiliser autofocussans valeur spring:form. autofocus="autofocus"fonctionne bien, cependant. Merci, @Jacob.
Sergei Tachenov

2
@Geek L'attribut autofocus, comme beaucoup d'autres, est un type d'attribut booléen. C'est pourquoi il n'est utilisé que de manière déclarative, pas en lui attribuant une valeur. Voir plus de détails dans les spécifications w3c: w3.org/TR/html5/infrastructure.html#boolean-attribute
n1kkou

34
document.forms[0].elements[0].focus();

Cela peut être affiné en utilisant une boucle par exemple. ne pas concentrer certains types de champs, les champs désactivés, etc. Mieux peut - être ajouter une classe = « mise au point automatique » au champ que vous avez réellement ne veulent concentré et boucle sur les formes [i] .elements [j] la recherche de ce className.

Quoi qu'il en soit: ce n'est normalement pas une bonne idée de faire cela sur chaque page. Lorsque vous vous concentrez sur une entrée, l'utilisateur perd la capacité d'ex. faites défiler la page à partir du clavier. Si cela est inattendu, cela peut être ennuyeux, alors la mise au point automatique ne se fait que lorsque vous êtes certain que l'utilisation du champ de formulaire sera ce que l'utilisateur souhaite faire. c'est à dire. si vous êtes Google.


3
Doit être la bonne réponse, car la question n'a pas de balise jquery.
Kalle H. Väravas

@ KalleH.Väravas non, il devrait être rejeté car il émet des hypothèses qui ne sont pas en cause, par exemple. il y a au moins un formulaire. Généralement, cela ne fonctionne pas.
9ilsdx 9rvj 0lo

18

L'expression jQuery la plus complète que j'ai trouvée fonctionne est (à l'aide de ici )

$(document).ready(function() {
    $('input:visible:enabled:first').focus();
});

1
J'utilisais ceci, j'ai remarqué qu'il fonctionne extrêmement lentement sur IE quand un grand nombre> 1000 de cases à cocher dans une table. Je ne sais pas quoi faire à ce sujet, vous devrez peut-être renoncer à vous concentrer sur le premier champ d'entrée.
Sam Watkins



5

Vous devez également ignorer toutes les entrées masquées.

for (var i = 0; document.forms[0].elements[i].type == 'hidden'; i++);
document.forms[0].elements[i].focus();

Je me trompe peut-être, mais cette boucle n'a pas de comportement défini si forms [0] n'a pas d'entrées cachées.
xtofl

Exactement. Il est utilisé pour ignorer toutes les principales entrées cachées. Et il est écrit en supposant qu'il y a des champs non cachés dans le formulaire. J'aurais pu le faire aussi avec jQuery (je posterai une autre réponse) mais vous n'avez pas mentionné que vous vouliez impliquer jQuery.
Marko Dumic

1
@MarkoDumic Pourquoi gaspiller de la mémoire si vous pouvez utiliser une whileinstruction?
Lucio

3

Mettre ce code à la fin de votre bodybalise focalisera automatiquement le premier élément activé visible et non masqué sur l'écran. Il traitera la plupart des cas que je peux proposer à court préavis.

<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>

1
Une chose à considérer ici est qu'il peut correspondre à des éléments qui ne sont pas eux-mêmes cachés, mais un ancêtre l'est. Cela nécessiterait de remonter le DOM et de tester la visibilité de chaque ancêtre, ce qui, à mon avis, est excessif pour ce genre de situation.
James Hughes

Qu'en est-il de <input type = "text" readonly = "readonly"> Je pense que vous devriez ajouter un tel cas à votre code. Normalement, les gens ne veulent pas se concentrer sur un champ de texte de saisie en lecture seule. En tout cas beau code et +1 merci!
Marco Demaio

Non testé mais je l'ai mis à jour avec! Forms [i] [j] .readonly! = Undefined
James Hughes


3

J'utilise ceci:

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

2

Cela obtient la première de toute entrée commune visible, y compris les zones de texte et les zones de sélection. Cela garantit également qu'ils ne sont pas masqués, désactivés ou en lecture seule. il permet également un div cible, que j'utilise dans mon logiciel (c'est-à-dire, première entrée à l'intérieur de ce formulaire).

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

1

Pour ceux qui utilisent JSF2.2 + et ne peuvent pas passer l'autofocus en tant qu'attribut sans valeur, utilisez ceci:

 p:autofocus="true"

Et ajoutez-le à l'espace de noms p (aussi souvent utilisé pt. Tout ce que vous voulez).

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

0

Avec AngularJS:

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

0

Cela inclut les zones de texte et exclut les boutons radio

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

0

Vous devriez pouvoir utiliser clientHeight au lieu de vérifier l'attribut d'affichage, car un parent pourrait masquer cet élément:

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;
                }
            }
        }
    }   
}

0

Sans bibliothèques tierces, utilisez quelque chose comme

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

Assurez-vous de prendre en compte toutes les balises d'élément de formulaire, excluez les balises masquées / désactivées comme dans les autres réponses, etc.


0

sans jquery, par exemple avec javascript classique:

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

fonctionne sur Safari mais pas sur Chrome 75 (avril 2019)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.