it-swarm.com.de

Wie finde ich heraus, welches DOM-Element den Fokus hat?

Ich möchte in JavaScript herausfinden, welches Element aktuell den Fokus hat. Ich habe das DOM durchgesehen und noch nicht gefunden, was ich brauche. Gibt es einen Weg, dies zu tun und wie?

Der Grund, warum ich danach gesucht habe:

Ich versuche, Tasten wie die Pfeile zu erstellen und enter durch eine Tabelle mit Eingabeelementen zu navigieren. Tab funktioniert jetzt, aber geben Sie ein, und Pfeile scheinen nicht standardmäßig. Ich habe den Key-Handling-Teil eingerichtet, aber jetzt muss ich herausfinden, wie ich den Fokus in den Event-Handling-Funktionen verschieben kann.

1201
Tony Peterson

Verwenden Sie document.activeElement , es wird in allen gängigen Browsern unterstützt.

Wenn Sie zuvor herausfinden wollten, welches Formularfeld den Fokus hat, konnten Sie dies nicht. Um die Erkennung in älteren Browsern zu emulieren, fügen Sie allen Feldern einen "Fokus" -Ereignishandler hinzu und zeichnen Sie das zuletzt fokussierte Feld in einer Variablen auf. Fügen Sie einen "Blur" -Handler hinzu, um die Variable bei einem Blur-Ereignis für das zuletzt fokussierte Feld zu löschen.

Verwandte Links:

1420
JW.

Wie JW bereits sagte, können Sie das aktuell fokussierte Element zumindest browserunabhängig nicht finden. Wenn Ihre App jedoch nur IE ist (einige sind ...), können Sie sie folgendermaßen finden:

document.activeElement

BEARBEITEN: Es sieht so aus, als hätte IE doch nicht alles falsch gemacht. Dies ist Teil des HTML5-Entwurfs und scheint zumindest von der neuesten Version von Chrome, Safari und Firefox unterstützt zu werden.

117
Wookai

Wenn Sie jQuery verwenden können, wird jetzt Folgendes unterstützt: focus. Stellen Sie nur sicher, dass Sie Version 1.6+ verwenden.

Mit dieser Anweisung erhalten Sie das aktuell fokussierte Element.

$(":focus")

From: So wählen Sie mit jQuery ein Element aus, das den Fokus darauf hat

78
William Denniss

document.activeElement ist jetzt Teil des HTML5-Arbeitsentwurfs Spezifikation, wird jedoch möglicherweise in einigen nicht-gängigen/mobilen/älteren Browsern noch nicht unterstützt. Sie können auf querySelector zurückgreifen (sofern dies unterstützt wird). Erwähnenswert ist auch, dass document.activeElementdocument.body zurückgibt, wenn kein Element fokussiert ist - auch wenn das Browserfenster nicht fokussiert ist.

Der folgende Code wird dieses Problem umgehen und auf querySelector zurückgreifen, um eine etwas bessere Unterstützung zu bieten.

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

Zu beachten ist außerdem der Leistungsunterschied zwischen diesen beiden Methoden. Das Abfragen des Dokuments mit Selektoren ist immer viel langsamer als der Zugriff auf die Eigenschaft activeElement. Siehe hierzu jsperf.com test .

42
Andy E

Selbst kann document.activeElement immer noch ein Element zurückgeben, wenn das Dokument nicht fokussiert ist (und daher ist nichts im Dokument fokussiert!)

Sie möchten möglicherweise dieses Verhalten, oder es spielt möglicherweise keine Rolle (z. B. innerhalb eines keydown -Ereignisses), aber wenn Sie Wenn Sie wissen möchten, dass etwas wirklich fokussiert ist, können Sie zusätzlich document.hasFocus() überprüfen.

Das Folgende gibt Ihnen das fokussierte Element, falls es eines gibt, oder null.

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

Es ist einfacher zu überprüfen, ob ein bestimmtes Element den Fokus hat:

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

Um zu überprüfen, ob irgendetwas fokussiert ist, ist es wieder komplexer:

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

Hinweis zur Robustheit : In dem Code, in dem nach document.body und document.documentElement gesucht wird, ist dies darauf zurückzuführen, dass einige Browser einen dieser Werte zurückgeben oder null, wenn nichts fokussiert ist.

Es ist nicht berücksichtigt, ob der <body> (oder vielleicht <html>) ein tabIndex -Attribut hatte und somit tatsächlich fokussiert werden konnte . Wenn Sie eine Bibliothek oder etwas schreiben und wollen, dass es robust ist, sollten Sie das wahrscheinlich irgendwie tun.


Hier ist eine ( schwere Airquotes) "Einzeiler" -Version, um das fokussierte Element zu erhalten, was konzeptionell komplizierter ist , weil Sie haben Wenn Sie etwas über Kurzschlüsse wissen, und Sie wissen, passt es offensichtlich nicht in eine Zeile, vorausgesetzt, Sie möchten, dass es lesbar ist.
Ich werde diesen nicht empfehlen. Aber wenn du ein 1337er bist, idk ... ist es da.
Sie können auch den Teil || null entfernen, wenn es Ihnen in einigen Fällen nichts ausmacht, false zu erhalten. (Sie könnten immer noch null bekommen, wenn document.activeElementnull ist):

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

Um zu überprüfen, ob ein bestimmtes Element fokussiert ist, können Sie alternativ Ereignisse verwenden , dies erfordert jedoch das Einrichten (und möglicherweise das Herunterfahren), und vor allem setzt ein Ausgangszustand:

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

Sie können die Annahme des Anfangszustands auf nicht ereignisgesteuerte Weise korrigieren, aber genauso gut können Sie sie stattdessen verwenden.

17
1j01

document.activeElement ist möglicherweise standardmäßig das <body> -Element, wenn keine fokussierbaren Elemente im Fokus stehen. Wenn ein Element fokussiert und das Browserfenster unscharf ist, behält activeElement das fokussierte Element weiterhin bei.

Wenn eines dieser beiden Verhaltensweisen nicht wünschenswert ist, ziehen Sie einen CSS-basierten Ansatz in Betracht: document.querySelector( ':focus' ).

14
Nate Whittaker

Ich mochte den Ansatz von Joel S, aber ich liebe auch die Einfachheit von document.activeElement. Ich habe jQuery verwendet und beides kombiniert. Ältere Browser, die document.activeElement nicht unterstützen, verwenden jQuery.data(), um den Wert von 'hasFocus' zu speichern. Neuere Browser verwenden document.activeElement. Ich gehe davon aus, dass document.activeElement eine bessere Leistung haben wird.

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

Ein kleiner Helfer, den ich für diese Zwecke in Mootools benutzt habe:

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

Auf diese Weise können Sie mit el.hasFocus() prüfen, ob das Element den Fokus hat, sofern startFocusTracking() für das angegebene Element aufgerufen wurde.

9
Joel S

JQuery unterstützt derzeit die Pseudoklasse :focus. Wenn Sie in der JQuery-Dokumentation danach suchen, überprüfen Sie unter "Selektoren", wo Sie auf die W3C-CSS-Dokumente verweisen. Ich habe mit Chrome, FF und IE 7+ getestet. Beachten Sie, dass <!DOCTYPE... auf der HTML-Seite vorhanden sein muss, damit es im IE funktioniert. In diesem Beispiel wird davon ausgegangen, dass Sie dem fokussierten Element eine ID zugewiesen haben:

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

Wenn Sie ein Objekt abrufen möchten, das eine Instanz von Element ist, müssen Sie document.activeElement verwenden. Wenn Sie jedoch ein Objekt abrufen möchten, das eine Instanz von Text ist, müssen Sie document.getSelection().focusNode verwenden.

Ich hoffe hilft.

7
rplaurindo

Bei der Verwendung von document.activeElement können Probleme auftreten. Erwägen:

<div contentEditable="true">
  <div>Some text</div>
  <div>Some text</div>
  <div>Some text</div>
</div>

Wenn sich der Benutzer auf ein inneres Div konzentriert, verweist document.activeElement weiterhin auf das äußere Div. Sie können document.activeElement nicht verwenden, um zu bestimmen, welcher der inneren Divs den Fokus hat.

Die folgende Funktion umgeht dies und gibt den fokussierten Knoten zurück:

function active_node(){
  return window.getSelection().anchorNode;
}

Wenn Sie lieber das fokussierte Element erhalten möchten, verwenden Sie:

function active_element(){
  var anchor = window.getSelection().anchorNode;
  if(anchor.nodeType == 3){
        return anchor.parentNode;
  }else if(anchor.nodeType == 1){
        return anchor;
  }
}
6
Nathan K

Wenn Sie andere Antworten lesen und mich selbst ausprobieren, scheint document.activeElement Ihnen das Element zu geben, das Sie in den meisten Browsern benötigen.

Wenn Sie einen Browser haben, der document.activeElement nicht unterstützt, wenn Sie jQuery verwenden, sollten Sie in der Lage sein, alle Fokusereignisse mit etwas sehr Einfachem wie diesem zu füllen (ungetestet, da ich keinen Browser habe, der diese Kriterien erfüllt) ):

if (typeof document.activeElement === 'undefined') { // Check browser doesn't do it anyway
  $('*').live('focus', function () { // Attach to all focus events using .live()
    document.activeElement = this; // Set activeElement to the element that has been focussed
  });
}
5
rjmunro

Wenn Sie jQuery verwenden, können Sie auf diese Weise herausfinden, ob ein Element aktiv ist:

$("input#id").is(":active");
5
Arne

Mit Dojo können Sie dijit.getFocus () verwenden.

4
Daniel Hartmann

Das folgende Snippet hat sich als nützlich erwiesen, um festzustellen, welches Element derzeit den Fokus hat. Kopieren Sie Folgendes in die Konsole Ihres Browsers und jede Sekunde werden die Details des aktuellen Elements gedruckt, das den Fokus hat.

setInterval(function() { console.log(document.querySelector(":focus")); }, 1000);

Sie können den console.log auch ändern, um etwas anderes abzumelden, damit Sie das genaue Element bestimmen können, wenn das Ausdrucken des gesamten Elements nicht dazu beiträgt, das Element zu bestimmen.

4
vegemite4me

Ich habe das hier nur geschrieben, um die Lösung zu finden, die ich mir letztendlich ausgedacht habe.

Ich habe eine Eigenschaft mit dem Namen document.activeInputArea erstellt und das HotKeys-Addon von jQuery verwendet, um Tastaturereignisse für Pfeiltasten, Tabulatoren und Eingaben abzufangen. Außerdem habe ich eine Ereignisbehandlungsroutine zum Klicken in Eingabeelemente erstellt.

Dann habe ich die activeInputArea jedes Mal angepasst, wenn sich der Fokus geändert hat, damit ich anhand dieser Eigenschaft herausfinden konnte, wo ich war.

Es ist jedoch einfach, das zu vermasseln, denn wenn Sie einen Fehler im System haben und der Fokus nicht dort ist, wo Sie glauben, ist es sehr schwierig, den richtigen Fokus wiederherzustellen.

3
Tony Peterson