How can I find out which DOM element has focus?

Posted by v1ral on Tue, 10 Dec 2019 20:49:21 +0100

I want to use JavaScript to find out what elements I'm focusing on. I've been browsing the DOM, but I haven't found what I need. Is there a way to do that?

I look for the reason:

I try to navigate through input element tables like arrow keys and enter. The tabs are now available, but can be entered, and by default, the arrows are not displayed. I've set up the key processing part, but now I need to figure out how to shift the focus in the event processing function.

#1 building

One of my little helpers in Mootools for these purposes:

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

This way, if startFocusTracking() has been called on a given element, you can use el.hasFocus() to check that the element has focus.

#2 building

If there is no focusable element, the document.activeElement may default to the < body > element. In addition, if an element is focused and the browser window is blurred, the active element will continue to retain the focused element.

If neither behavior is ideal, consider a CSS based approach: document. Queryselector (': focus').

#3 building

There are potential problems with using document.activeElement. Consider:

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

If the user focuses on the internal div, the document.activeElement still references the external Div. You cannot use document.activeElement to determine which internal div has focus.

The following function solves this problem and returns the focus node:

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

If you want focused elements, use:

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

#4 building

I like the way Joel S uses it, but I also like the simplicity of document. Activeelement. I use jQuery and combine the two. document.activeElement legacy browsers will use jQuery.data() to store the value of 'hasFocus' without support. Newer browsers will use document.activeElement. I think document.activeElement will have better performance.

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

#5 building

If you want to get an object as an Element instance, you must use document.activeElement; however, if you want to get an object as a Text instance, you must use document.getSelection().focusNode.

I hope it will help you.

Topics: JQuery Javascript