Question Comment puis-je savoir quel élément DOM a le focus?


Je voudrais savoir, en Javascript, quel élément a actuellement le focus. J'ai regardé à travers les DOM et n'ai pas encore trouvé ce dont j'avais besoin. Y a-t-il un moyen de faire cela, et comment?

La raison pour laquelle je cherchais ceci:

J'essaie de faire des clés comme les flèches et enter naviguer dans une table d'éléments d'entrée. Tab fonctionne maintenant, mais entrez et flèches ne par défaut, il semble. J'ai configuré la partie manipulation des clés, mais maintenant je dois trouver comment déplacer la mise au point dans les fonctions de gestion des événements.


1038
2018-01-30 20:21


origine


Réponses:


Utilisation document.activeElement, il est pris en charge dans tous les principaux navigateurs.

Auparavant, si vous essayiez de savoir quel champ de formulaire a le focus, vous ne pourriez pas. Pour émuler la détection dans les navigateurs plus anciens, ajoutez un gestionnaire d'événement "focus" à tous les champs et enregistrez le dernier champ ciblé dans une variable. Ajouter un gestionnaire "flou" pour effacer la variable lors d'un événement de flou pour le dernier champ ciblé.

Liens connexes:


1222
2018-01-30 20:34



Comme dit par JW, vous ne pouvez pas trouver l'élément ciblé actuel, au moins de manière indépendante du navigateur. Mais si votre application est uniquement IE (certains sont ...), vous pouvez le trouver de la manière suivante:

document.activeElement

EDIT: On dirait qu'EI n'a pas tout mal après tout, cela fait partie du brouillon HTML5 et semble être supporté par la dernière version de Chrome, Safari et Firefox au moins.


106
2017-08-27 17:33



Si vous pouvez utiliser jQuery, il prend maintenant en charge: focus, assurez-vous simplement d'utiliser la version 1.6+.

Cette déclaration vous obtiendra l'élément actuellement ciblé.

$(":focus")

De: Comment sélectionner un élément qui a le focus avec jQuery


77
2017-10-19 13:01



document.activeElement est maintenant partie du brouillon de travail HTML5 spécifications, mais il n'est peut-être pas encore pris en charge dans certains navigateurs non majeurs / mobiles / anciens. Vous pouvez revenir à querySelector (si cela est supporté). Il est également important de mentionner que document.activeElement reviendra document.body si aucun élément n'est focalisé - même si la fenêtre du navigateur n'a pas de focus.

Le code suivant va contourner ce problème et revenir à querySelector donner un meilleur soutien.

var focused = document.activeElement;
if (!focused || focused == document.body)
    focused = null;
else if (document.querySelector)
    focused = document.querySelector(":focus");

Une chose additionnelle à noter est la différence de performance entre ces deux méthodes. Interroger le document avec des sélecteurs sera toujours beaucoup plus lent que d'accéder à la activeElement propriété. Regarde ça test jsperf.com.


39
2017-08-06 19:32



document.activeElement peut par défaut à la <body> élément si aucun élément focalisable n'est en focus. De plus, si un élément est ciblé et que la fenêtre du navigateur est floue, activeElement continuera à détenir l'élément ciblé.

Si l'un de ces deux comportements n'est pas souhaitable, envisagez une approche basée sur CSS: document.querySelector( ':focus' ).


13
2017-11-29 18:51



Par lui-même, document.activeElement peut toujours retourner un élément si le document n'est pas focalisé (et donc rien dans le document est concentré!)

Toi mai vouloir ce comportement, ou mai pas d'importance (par exemple dans un keydown événement), mais si vous avez besoin de savoir que quelque chose est réellement concentré, vous pouvez également vérifier document.hasFocus().

Ce qui suit vous donnera l'élément ciblé s'il y en a un, ou bien null.

var focused_element = null;
if (
    document.hasFocus() &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement
) {
    focused_element = document.activeElement;
}

Pour vérifier si un spécifique l'élément a le focus, c'est plus simple:

var input_focused = document.activeElement === input && document.hasFocus();

Pour vérifier si n'importe quoi est concentré, c'est plus complexe encore:

var anything_is_focused = (
    document.hasFocus() &&
    document.activeElement !== null &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement
);

Note de robustesse: Dans le code où les contrôles contre document.body et document.documentElement, car certains navigateurs renvoient l'un de ces null quand rien n'est concentré.

Il ne tient pas compte si le <body> (ou peut-être <html>) avait un tabIndex attribuer et donc pourrait effectivement être concentré. Si vous écrivez une bibliothèque ou quelque chose et que vous voulez qu'elle soit robuste, vous devriez probablement gérer cela d'une manière ou d'une autre.


Voici un (lourd airquotes) version "one-liner" d'obtenir l'élément ciblé, qui est conceptuellement plus compliqué parce que vous devez connaître les courts-circuits, et vous savez, cela ne tient évidemment pas sur une seule ligne, en supposant que vous voulez qu'il soit lisible.
Je ne vais pas recommander celui-ci. Mais si vous êtes un 1337 hax0r, idk ... c'est là.
Vous pouvez également supprimer le || null partie si cela ne vous dérange pas false dans certains cas. (Vous pourriez toujours obtenir null si document.activeElement est null):

var focused_element = (
    document.hasFocus() &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement &&
    document.activeElement
) || null;

Pour vérifier si un élément spécifique est ciblé, vous pouvez également pourrait utiliser des événements, mais de cette façon nécessite une configuration (et éventuellement un démontage), et surtout, suppose un état initial:

var input_focused = false;
input.addEventListener("focus", function() {
    input_focused = true;
});
input.addEventListener("blur", function() {
    input_focused = false;
});

Vous pouvez corriger l'hypothèse de l'état initial en utilisant la méthode non événementielle, mais vous pouvez tout aussi bien l'utiliser à la place.


12
2017-09-08 18:47



J'ai aimé l'approche utilisée par Joel S, mais j'aime aussi la simplicité de document.activeElement. J'ai utilisé jQuery et combiné les deux. Anciens navigateurs ne prenant pas en charge document.activeElement utilisera jQuery.data() pour stocker la valeur de 'hasFocus'. Les nouveaux navigateurs utiliseront document.activeElement. Je suppose que document.activeElement aura de meilleures performances.

(function($) {
var settings;
$.fn.focusTracker = function(options) {
    settings = $.extend({}, $.focusTracker.defaults, options);

    if (!document.activeElement) {
        this.each(function() {
            var $this = $(this).data('hasFocus', false);

            $this.focus(function(event) {
                $this.data('hasFocus', true);
            });
            $this.blur(function(event) {
                $this.data('hasFocus', false);
            });
        });
    }
    return this;
};

$.fn.hasFocus = function() {
    if (this.length === 0) { return false; }
    if (document.activeElement) {
        return this.get(0) === document.activeElement;
    }
    return this.data('hasFocus');
};

$.focusTracker = {
    defaults: {
        context: 'body'
    },
    focusedElement: function(context) {
        var focused;
        if (!context) { context = settings.context; }
        if (document.activeElement) {
            if ($(document.activeElement).closest(context).length > 0) {
                focused = document.activeElement;
            }
        } else {
            $(':visible:enabled', context).each(function() {
                if ($(this).data('hasFocus')) {
                    focused = this;
                    return false;
                }
            });
        }
        return $(focused);
    }
};
})(jQuery);

10
2018-02-04 12:36



Un petit assistant que j'ai utilisé à ces fins dans Mootools:

FocusTracker = {
    startFocusTracking: function() {
       this.store('hasFocus', false);
       this.addEvent('focus', function() { this.store('hasFocus', true); });
       this.addEvent('blur', function() { this.store('hasFocus', false); });
    },

    hasFocus: function() {
       return this.retrieve('hasFocus');
    }
}

Element.implement(FocusTracker);

De cette façon, vous pouvez vérifier si l'élément a le focus avec el.hasFocus() à condition que startFocusTracking() a été appelé sur l'élément donné.


9
2018-03-10 23:10



JQuery prend en charge le :focus pseudo-classe comme de courant. Si vous le recherchez dans la documentation de JQuery, vérifiez sous "Sélecteurs" où il vous dirige vers W3C CSS docs. J'ai testé avec Chrome, FF et IE 7+. Notez que pour qu'il fonctionne dans IE, <!DOCTYPE... doit exister sur la page html. Voici un exemple en supposant que vous avez attribué un identifiant à l'élément qui a le focus:

$(":focus").each(function() {
  alert($(this).attr("id") + " has focus!");
});

7
2017-07-17 05:52



Si vous voulez obtenir un objet qui est une instance de Element, Tu dois utiliser document.activeElement, mais si vous voulez obtenir un objet qui est une instance de Text, vous devez utiliser document.getSelection().focusNode.

J'espère aider.


7
2018-03-01 07:36