Est-il possible de se concentrer sur une <div> en utilisant la fonction JavaScript focus ()?

227

Est-il possible de se concentrer sur une fonction <div>utilisant JavaScript focus()?

J'ai un <div>tag

<div id="tries">You have 3 tries left</div>

J'essaie de me concentrer sur ce qui précède en <div>utilisant:

document.getElementById('tries').focus();

Mais ça ne marche pas. Quelqu'un pourrait-il suggérer quelque chose ...?

OM The Eternity
la source
3
Que voulez-vous qu'il se passe lorsque vous le «concentrez»? Les divs n'acceptent pas d'entrée, alors voulez-vous flasher la bordure, ou flasher un surlignage d'arrière-plan, etc.?
Michael Shimmins
@Michael, oui j'ai besoin de ce <div> pour attirer l'attention de l'utilisateur ...
OM The Eternity
1
doublon possible de Quels éléments HTML peuvent recevoir le focus?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@MichaelShimmins et n'importe qui d'autre, les éléments <div> peuvent accepter une entrée si vous avez défini contenteditable sur true. (Raison pour laquelle je me suis renseigné)
MattOlivos
1
@MichaelShimmins divpeut accepter une entrée si elle déborde et affiche une barre de défilement. Quand un divavec une barre de défilement est focalisé, les touches fléchées feront défiler son contenu (au lieu du contenu d'autres éléments tels que body).
Rory O'Kane

Réponses:

101
window.location.hash = '#tries';

Ceci défilera jusqu'à l'élément en question, essentiellement "le focalisera".

Casey Chu
la source
2
@Casey Chu: Son fonctionne bien dans ie mais pas dans firefox, avez-vous une idée?
Haseeb Akhtar
Cela ne fonctionne pas dans certaines versions de Chrome ... Cependant, la solution @vinoths le fait
Charliemops
1
Cela fonctionne mais ... avec Angular vous auriez des problèmes !!
Carlos Verdes
@CarlosVerdes; Existe-t-il une solution pour Angular?
Mac Vicious
3
ne répondant pas à la question «focus», cela ne devrait pas être la bonne réponse. dans mon cas, je veux me concentrer sur une div «contentEditable», et votre astuce n'aide pas.
arnaudambro
453

Oui, c'est possible. Pour ce faire, vous devez attribuer un tabindex ...

<div tabindex="0">Hello World</div>

Un tabindex de 0 mettra la balise "dans l'ordre de tabulation naturel de la page". Un nombre plus élevé lui donnera un ordre de priorité spécifique, où 1 sera le premier, 2 le second et ainsi de suite.

Vous pouvez également donner un tabindex de -1, ce qui rendra la div uniquement focalisable par script, pas l'utilisateur.

document.getElementById('test').onclick = function () {
    document.getElementById('scripted').focus();
};
div:focus {
    background-color: Aqua;
}
<div>Element X (not focusable)</div>
<div tabindex="0">Element Y (user or script focusable)</div>
<div tabindex="-1" id="scripted">Element Z (script-only focusable)</div>
<div id="test">Set Focus To Element Z</div>

Évidemment, il est dommage d'avoir un élément que vous pouvez focaliser par script que vous ne pouvez pas focaliser par une autre méthode d'entrée (surtout si un utilisateur est uniquement clavier ou contraint de manière similaire). Il existe également toute une série d'éléments standard pouvant être focalisés par défaut et contenant des informations sémantiques pour aider les utilisateurs. Utilisez ces connaissances à bon escient.

Fenton
la source
6
@Michael Shimmins, Cela permet à l'élément d'être focalisable (de manière non standard!) Avec focus().
strager
2
@Olical - Je suis presque sûr que c'est exactement ce que dit la dernière ligne de mai réponse. Faites-moi savoir si vous pensez qu'il y a un problème qui nécessite une modification.
Fenton
2
Si on ne sait pas, en ajoutant tabindexun élément va faire vario, qui permet aux focus()et blur()méthodes, et vous pouvez déclencher une mise au point comme celui - ci:document.getElementById('tries').focus();
pilaf
4
Salut @SteveOwen - il semble toujours fonctionner dans Firefox v42. J'ai ajouté un extrait à cette réponse afin que vous puissiez l'exécuter et le tester.
Fenton
9
L'utilisation de @SteveOwen window.location.hash = ...est le moyen de le faire. focus ne signifie pas «mettre en vue», cela signifie simplement placer littéralement le focus sur cet élément.
Fenton
76

document.getElementById('tries').scrollIntoView()travaux. Cela fonctionne mieux que window.location.hash lorsque vous avez un positionnement fixe.

vinoths
la source
2
Notez que cette solution ne fonctionnera pas dans IE, Opera ou Safari.
AlecRust
1
Je viens d'essayer cela dans Chrome 65 et cela ne fonctionne pas. Le div de superposition défile dans la vue, mais le focus est toujours dans le div d'arrière-plan. La seule façon infaillible que je connaisse est d'avoir un élément tabable (utilisant un tabindexattribut) dans le div de superposition et de l'utiliser focus()sur cet élément à la place.
thdoan
@ om-the-eternity a déjà déclaré qu'il voulait que le div attire l'attention de l'utilisateur, donc ce dont il a besoin n'est pas de se concentrer réellement (même en travaillant, ce n'est pas correct de le faire) le div, mais de le porter à l'écran , cela résout cela
Omar Vazquez
Si je le fais dans Chrome, il revient toujours au champ de saisie toujours focalisé. Surtout si le chargement de la page n'est pas encore terminé.
Roger Krueger
37

Vous pouvez utiliser tabindex

<div tabindex="-1"  id="tries"></div>

La valeur tabindex peut permettre un comportement intéressant.

  • Si on lui donne une valeur de "-1", l'élément ne peut pas être tabulé mais le focus peut être donné à l'élément par programme (en utilisant element.focus ()).
  • Si on lui donne une valeur de 0, l'élément peut être focalisé via le clavier et tombe dans le flux de tabulation du document. Les valeurs supérieures à 0 créent un niveau de priorité, 1 étant le plus important.
Sarath Ak
la source
1
Wow, merci truc cool. Je vous remercie! Je n'aurais pas compris cela autrement.
AVProgrammer
Économiseur de vie, merci. Dans Edge, une div peut être focalisée, mais pas dans Chrome sans cette astuce. La réponse acceptée est excellente mais je ne veux pas de partie supplémentaire dans l'URL.
Cal
sauver la vie.Fonctionne bien avec le chrome et Firefox
Susampath
14
<div id="inner" tabindex="0">
    this div can now have focus and receive keyboard events
</div>
Azad
la source
Cela fonctionne pour moi dans Chrome / Chrome 46 uniquement combiné avec$('#inner').focus();
TNT
2

Je voulais suggérer quelque chose comme Michael Shimmin mais sans coder en dur des éléments comme l'élément ou le CSS qui lui est appliqué.

J'utilise seulement jQuery pour ajouter / supprimer la classe, si vous ne voulez pas utiliser jquery, vous avez juste besoin d'un remplacement pour add / removeClass

--Javascript

function highlight(el, durationMs) { 
  el = $(el);
  el.addClass('highlighted');
  setTimeout(function() {
    el.removeClass('highlighted')
  }, durationMs || 1000);
}

highlight(document.getElementById('tries'));

--CSS

#tries {
    border: 1px solid gray;
}

#tries.highlighted {
    border: 3px solid red;
}
Juan Mendes
la source
1

document.getElementById('test').onclick = function () {
    document.getElementById('scripted').focus();
};
div:focus {
    background-color: Aqua;
}
<div>Element X (not focusable)</div>
<div tabindex="0">Element Y (user or script focusable)</div>
<div tabindex="-1" id="scripted">Element Z (script-only focusable)</div>
<div id="test">Set Focus To Element Z</div>

san jing
la source
0

Pour faire clignoter la bordure, vous pouvez faire ceci:

function focusTries() {
    document.getElementById('tries').style.border = 'solid 1px #ff0000;'
    setTimeout ( clearBorder(), 1000 );
}

function clearBorder() {
    document.getElementById('tries').style.border = '';
}

Cela rendra la bordure rouge fixe pendant 1 seconde, puis retirez-la à nouveau.

Michael Shimmins
la source