$ .focus () ne fonctionne pas

155

Le dernier exemple desfocus() états de documentation de jQuery

$('#id').focus()

devrait rendre l'entrée focalisée (active). Je n'arrive pas à faire fonctionner ça.

Même dans la console de ce site, je l'essaye pour le champ de recherche

$('input[name="q"]').focus()

et je n'obtiens rien. Des idées?

Sam Selikoff
la source
2
Pouvez-vous nous montrer votre code?
Adil du
Nous devrons en savoir plus, car cela fonctionne bien pour moi: jsfiddle.net/G7hwR/1 cliquez simplement n'importe où dans le panneau de droite et il se concentre ...
Rob G
Mais l'accent mis sur cette page ne devrait-il pas fonctionner? L'extrait que j'ai fourni?
Sam Selikoff
Cela dépend de ce qu'il contient; si ce n'est à l'intérieur de rien, il est probablement exécuté avant même que la page ne s'affiche ...
Rob G
Pour ceux qui viennent ici de la recherche: les outils de développement intégrés du navigateur peuvent interférer avec la fonctionnalité focus(). Plus d'informations
aexl

Réponses:

392

En fait, l'exemple que vous avez donné pour vous concentrer sur ce site fonctionne très bien, tant que vous n'êtes pas concentré sur la console. La raison pour laquelle cela ne fonctionne pas est simplement parce que cela ne vole pas l'attention de la console de développement. Si vous exécutez le code suivant dans votre console, puis cliquez rapidement dans la fenêtre de votre navigateur après, vous le verrez se concentrer sur la zone de recherche:

setTimeout(function() { $('input[name="q"]').focus() }, 3000);

Quant à votre autre, la seule chose qui m'a posé des problèmes dans le passé, c'est l'ordre des événements. Vous ne pouvez pas appeler focus () sur un élément qui n'a pas été attaché au DOM. L'élément que vous essayez de focaliser a-t-il déjà été attaché au DOM?

Justin Warkentin
la source
1
Génial! Cela vous a-t-il aidé à résoudre vos deux problèmes? Dans l'affirmative, pourriez-vous la marquer comme la bonne réponse? J'apprécierais beaucoup: D
Justin Warkentin
4
n'utilisez pas les outils de développement lorsque vous n'utilisez que $ ('input [name = "q"]'). focus (); ou ne fonctionne pas
Amitābha
12
Wow, j'avais du mal avec ça pendant des mois, je viens de voir que cela est dû à l'ouverture de la console du développeur. Le mien l'est toujours. Je vous remercie!
Alex Turpin
20
+1 pour "Vous ne pouvez pas appeler focus () sur un élément qui n'a pas été attaché au DOM." En outre, il semble que vous ne pouvez pas l'appeler sur des éléments cachés.
tandrewnichols
1
Utiliser setTimeoutpour résoudre les problèmes d'ordre des opérations rend la maintenance très pénible. Si un bogue apparaît, il est vraiment difficile de le déboguer. Partout où vous insérez l'élément dans le DOM, il devrait .focus()y appeler .
Kevin Beal
55

J'ai trouvé une solution ailleurs sur le net ...

$('#id').focus();

n'a pas marché.

$('#id').get(0).focus();

a fonctionné.

Cymro
la source
4
J'ai voté pour cette solution simplement parce qu'elle fonctionnait pour moi alors que la solution la plus populaire sur cette page ne fonctionnait pas. ;-)
chriv
La deuxième option semble simplement saisir l'élément dom et utiliser la version javascript standard au lieu de la version jquery.
danielson317
7
Se pourrait-il que vous ayez plusieurs éléments avec l'identifiant "id" sur votre page? Le DOM ne se cassera pas dans ce cas, mais vous ne pouvez pas non plus attribuer le focus à plusieurs éléments
DerpyNerd
J'ai trouvé que je devais le faire avec un window.setTimeout avec un retard de 0, et puis tout va bien. Merci. Tout le reste que j'ai essayé a échoué dans un modal bootstrap.
Wade Hatler
23

Certaines des réponses ici suggèrent d'utiliser setTimeoutpour retarder le processus de focalisation sur l'élément cible. L'un d'eux mentionne que la cible se trouve dans une boîte de dialogue modale. Je ne peux pas commenter davantage l'exactitude de la setTimeoutsolution sans connaître les détails précis de l'endroit où elle a été utilisée. Cependant, j'ai pensé que je devrais fournir une réponse ici pour aider les personnes qui se heurtent à ce fil comme je l'ai fait

Le fait est que vous ne pouvez pas vous concentrer sur un élément qui n’est pas encore visible . Si vous rencontrez ce problème, assurez-vous que la cible est réellement visible lorsque la tentative de mise au point est effectuée. Dans mon cas, je faisais quelque chose dans ce sens

$('#elementid').animate({left:0,duration:'slow'});
$('#elementid').focus();

Cela n'a pas fonctionné. Je n'ai réalisé ce qui se passait que lorsque j'ai exécuté $ ('# elementid'). Focus () `depuis la console qui a fonctionné. La différence - dans mon code au-dessus de la cible, il n'y a aucune certitude que la cible sera effectivement visible car l'animation peut ne pas être complète . Et là se trouve l'indice

$('#elementid').animate({left:0,duration:'slow',complete:focusFunction});

function focusFunction(){$('#elementid').focus();}

fonctionne comme prévu. J'avais moi aussi initialement mis en place une setTimeoutsolution et cela fonctionnait aussi. Cependant, un délai d'expiration choisi arbitrairement est lié à interrompre la solution tôt ou tard en fonction de la lenteur avec laquelle le périphérique hôte procède au processus de vérification de la visibilité de l'élément cible.

DroidOS
la source
L'astuce pertinente pour moi était "s'assurer que la cible est réellement visible". cela devient pertinent lorsque vous essayez de vous concentrer sur des éléments rendus conditionnellement.
charlie carver
Ou quand l'élément à se concentrer a visibility:hidden- il ne sera pas concentré.
bakrall le
"vous ne pouvez pas vous concentrer sur un élément qui n'est pas encore visible" - je vous aime. En ajoutant simplement un délai de 100 ms, je pourrais déclencher le focus sur ma boîte de recherche cachée. Merci!
LuBre
Méfiez-vous des délais d'attente. Ce qui fonctionne sur votre machine de développement peut très bien ne pas fonctionner sur une autre.
DroidOS
15

si vous utilisez bootstrap + modal, cela a fonctionné pour moi:

  $(myModal).modal('toggle');
  $(myModal).on('shown.bs.modal', function() {
    $('#modalSearchBox').focus()
  });
Loup359
la source
8

Juste au cas où quelqu'un d'autre trébucherait sur cette question et aurait la même situation que moi - j'essayais de définir le focus après avoir cliqué sur un autre élément, mais le focus ne semblait pas fonctionner. Il s'avère que j'avais juste besoin d'un e.preventDefault();- voici un exemple:

$('#recipients ul li').mousedown(function(e) {
    // add recipient to list
    ...
    // focus back onto the input
    $('#message_recipient_input').focus();
    // prevent the focus from leaving
    e.preventDefault();
});

Cela a aidé:

Si vous appelez HTMLElement.focus () à partir d'un gestionnaire d'événements mousedown, vous devez appeler event.preventDefault () pour empêcher le focus de quitter le HTMLElement. Source: https://developer.mozilla.org/en/docs/Web/API/HTMLElement/focus

Ben
la source
2
Le seul fonctionne! Trigger est un div popup, cliquez sur cache le div et mettez une valeur dans une zone de texte (pas celle qui doit être focalisée). Sans preventDefault, cette zone de texte est toujours focalisée quoi qu'il
arrive -__-
4

Je me rends compte que c'est vieux, mais je l'ai rencontré aujourd'hui. Aucune des réponses n'a fonctionné pour moi, ce que j'ai trouvé qui a fonctionné était setTimeout. Je voulais que mon focus soit placé sur le fichier d'entrée d'un modal, en utilisant le setTimeout fonctionné. J'espère que cela t'aides!

user3861385
la source
Moi aussi! ET la durée du délai a vraiment fait une différence. Stupide IE.
eaglei22
1
Mais cela ne fonctionne pas sur les appareils mobiles. Les navigateurs mobiles ignorent dans la plupart des cas tout ce qui est à l'intérieur de setTimeout
Kosmonaft
1
En règle générale, l'utilisation setTimeoutest une mauvaise solution. Vous ne pouvez pas garantir le temps d'exécution sur la machine de l'utilisateur, donc les éléments dépendant du temps sont extrêmement fragiles.
Nathan
3

J'ai aussi eu ce problème. La solution qui a fonctionné dans mon cas utilisait la propriété tabindex sur l'élément HTML.

J'utilisais ng-repeatpour certains éléments li dans une liste et je n'ai pas pu mettre le focus sur le premier li en utilisant .focus (), j'ai donc simplement ajouté l'attribut tabindex à chaque li pendant la boucle.

alors maintenant <li ng-repeat="user in users track by $index" tabindex="{{$index+1}}"></li>

Ce +1 était l'index commence à 0. Assurez-vous également que l'élément est présent dans le DOM avant d'appeler la fonction .focus ()

J'espère que ça aide.

Kumar Shubham
la source
2

Pour ceux qui ont le problème de ne pas fonctionner parce que vous avez utilisé "$ (element) .show ()". Je l'ai résolu de la manière suivante:

 var textbox = $("#otherOption");
 textbox.show("fast", function () {
    textbox[0].focus();
  });

Vous n'avez donc pas besoin d'une minuterie, elle s'exécutera une fois la méthode show terminée.

Rolando Retana
la source
Ceci est valable pour toute autre transition: slideDown(), fadeIn(), etc.
Álvaro González
2

Ajoutez un délai avant focus (). 200 ms suffisent

function focusAndCursor(selector){
  var input = $(selector);
  setTimeout(function() {
    // this focus on last character if input isn't empty
    tmp = input.val(); input.focus().val("").blur().focus().val(tmp);
  }, 200);
}
Abel
la source
0

J'avais à nouveau ce problème, et croyez-le ou non, tout ce que j'avais à faire était de fermer les outils de développement. Apparemment, l'onglet Console a la priorité sur le contenu de la page.

aexl
la source
0

Assurez-vous que l'élément et ses parents sont visibles. Vous ne pouvez pas utiliser le focus sur les éléments masqués

mariovials
la source
-1

SOLUTION SUPPLÉMENTAIRE J'ai eu le même problème où focus () ne semblait pas fonctionner, mais il s'est finalement avéré que ce qui était nécessaire était de défiler jusqu'à la bonne position:

Martin
la source
-1

Pour mon cas, j'ai dû spécifier un index d'onglet ( -1si seulement focusable via un script)

<div tabindex='-1'>
<!-- ... -->
</div>
Alexandre Daubricourt
la source