代码之家  ›  专栏  ›  技术社区  ›  Tony Peterson

如何找出哪个DOM元素具有焦点?

  •  1615
  • Tony Peterson  · 技术社区  · 16 年前

    我寻找这个的原因是:

    我试着把钥匙做成箭头一样 enter 浏览输入元素表。选项卡现在可以使用,但默认情况下,输入和箭头似乎不起作用。我已经设置了关键处理部分,但现在我需要弄清楚如何在事件处理功能中转移注意力。

    21 回复  |  直到 6 年前
        1
  •  1738
  •   Juan Delgado    5 年前

    使用 document.activeElement ,它在所有主流浏览器中都受支持。

    activeElement 你可以使用模糊; document.activeElement.blur() activeElement body .

    相关链接:

        2
  •  138
  •   Iurii Tkachenko Wookai    4 年前

    document.activeElement
    

    看起来IE并没有完全出错,毕竟这是HTML5草案的一部分,似乎至少得到了最新版本的Chrome、Safari和Firefox的支持。

        3
  •  91
  •   Community CDub    8 年前

    如果你能使用jQuery,它现在支持:focus,只要确保你使用的是1.6+版本。

    此语句将为您提供当前关注的元素。

    $(":focus")
    

    发件人: How to select an element that has focus on it with jQuery

        4
  •  48
  •   Andy E    13 年前

    document.activeElement 现在是 part of the HTML5 working draft querySelector (如果支持的话)。同样值得一提的是 document.body 如果没有元素被聚焦,即使浏览器窗口没有焦点。

    query选择器 提供更好的支持。

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

    另外需要注意的是这两种方法之间的性能差异。使用选择器查询文档总是比访问文档慢得多 activeElement 财产。看这个 jsperf.com test .

        5
  •  34
  •   1j01    7 年前

    document.activeElement 专注!)

    可能 想要那种行为,否则 可能 无关紧要(例如在 keydown 事件),但如果你需要知道某事实际上是专注的,你可以额外检查 document.hasFocus() .

    以下内容将为您提供焦点元素(如果有的话),否则 null .

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

    具体的 元素有焦点,它更简单:

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

    检查是否 任何事物 专注,它又变得更复杂了:

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

    稳健性说明 :在它检查的代码中 document.body document.documentElement ,这是因为有些浏览器返回其中之一或 无效的 当什么都不集中的时候。

    <body> <html> )有一个 tabIndex 属性,因此 实际上可以集中注意力 如果你正在编写一个库或其他东西,并希望它健壮,你可能应该以某种方式处理它。


    这是一个( 重的 airquotes)获得焦点元素的“单行”版本,即
    我不会推荐这个。但如果你是1337公顷,idk。它就在那里。
    您还可以删除 || null 如果你不介意的话,就分手吧 false 在某些情况下。(你仍然可以得到 无效的 如果 document.activeElement 无效的 ):

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

    可能会 使用事件,但这种方式需要设置(并可能拆卸),重要的是, 假设初始状态 :

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

    您可以通过使用非事件方式来修复初始状态假设,但也可以直接使用它。

        6
  •  19
  •   Nate Whittaker    11 年前

    document.activeElement <body> activeElement 将继续保持焦点元素。

    如果这两种行为中的任何一种都不可取,请考虑基于CSS的方法: document.querySelector( ':focus' ) .

        7
  •  13
  •   vegemite4me    7 年前

    我发现以下代码片段在尝试确定哪个元素当前具有焦点时很有用。将以下内容复制到浏览器的控制台中,它每秒都会打印出具有焦点的当前元素的详细信息。

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

    请随意修改 console.log

        8
  •  12
  •   Bonifacio2 endurogizer    11 年前

    document.activeElement document.activeElement jQuery.data() 存储“hasFocus”的值。较新的浏览器将使用 document.activeElement 我推测 document.activeElement 将有更好的性能。

    (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);
    
        9
  •  11
  •   Jason    14 年前

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

    通过这种方式,您可以检查元素是否具有焦点 el.hasFocus() startFocusTracking() 已对给定元素进行调用。

        10
  •  9
  •   Andrew Wynham    14 年前

    JQuery确实支持 :focus 伪类为当前。如果您在JQuery文档中查找它,请在“选择器”下查看它指向的位置 W3C CSS docs <!DOCTYPE... 必须存在于html页面上。以下是一个示例,假设您已经为具有焦点的元素分配了一个id:

    $(":focus").each(function() {
      alert($(this).attr("id") + " has focus!");
    });
    
        11
  •  9
  •   rplaurindo    7 年前

    Element document.activeElement ,但如果你想得到一个对象,它是 Text document.getSelection().focusNode .

    我希望有帮助。

        12
  •  7
  •   Arne    13 年前

    使用document.activeElement可能存在问题。考虑:

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

    如果用户关注内部div,则document.activeElement仍会引用外部div。您不能使用document.active Element来确定哪个内部div有焦点。

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

    function active_element(){
      var anchor = window.getSelection().anchorNode;
      if(anchor.nodeType == 3){
            return anchor.parentNode;
      }else if(anchor.nodeType == 1){
            return anchor;
      }
    }
    
        13
  •  7
  •   Nathan K    10 年前

    如果你使用的是jQuery,你可以用它来判断一个元素是否处于活动状态:

    $("input#id").is(":active");
    
        14
  •  6
  •   rjmunro    14 年前

    阅读其他答案,并尝试自己,似乎 document.activeElement 将为您提供大多数浏览器中所需的元素。

    如果你有一个不支持document.activeElement的浏览器,如果你有jQuery,你应该能够用这样简单的东西在所有焦点事件上填充它(未经测试,因为我手头没有符合这些标准的浏览器):

    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
      });
    }
    
        15
  •  5
  •   Daniel Hartmann    13 年前

    只是把这个放在这里,给出我最终想出的解决方案。

    我创建了一个名为document.activeInputArea的属性,并使用jQuery的HotKeys插件来捕获箭头键、制表符和回车键的键盘事件,还创建了用于点击输入元素的事件处理程序。

    不过,很容易搞砸,因为如果系统中有错误,而焦点不在你认为的位置,那么很难恢复正确的焦点。

        16
  •  4
  •   Tony Peterson    16 年前

    使用dojo,您可以使用dijit.getFocus()