当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何找出哪个DOM元素具有焦点?》经验,为你挑选了13个好方法。

我想在JavaScript中找出目前关注哪个元素.我一直在浏览DOM,但还没找到我需要的东西.有没有办法做到这一点,以及如何?

我之所以在寻找这个:

我正在尝试制作像箭头一样的键,并enter在输入元素表中导航.选项卡现在可以使用,但是输入,并且默认情况下不显示箭头.我已经设置了密钥处理部分,但现在我需要弄清楚如何在事件处理函数中移动焦点.



1> JW...:

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

以前,如果您试图找出哪个表单字段具有焦点,则不能.要在旧浏览器中模拟检测,请向所有字段添加"焦点"事件处理程序,并将最后一个焦点字段记录在变量中.添加"模糊"处理程序以清除最后一个焦点字段的模糊事件时的变量.

相关链接:

activeElement浏览器兼容性

document.activeElement的jQuery替代方案


不确定IE,但FF和Safari都返回BODY元素.
@Rudie,@斯图尔特:我已经建立了你的小提琴来创建一个更精致的游乐场:http://jsfiddle.net/mklement/72rTF/.您会发现唯一可以实际关注这种"div"的主要浏览器(截至2012年底)是Firefox 17,并且只能通过_tabbing_来实现.所有主要浏览器通过`document.activeElement`返回的元素类型仅限于与_input_相关的元素.如果没有这样的元素有焦点,所有主流浏览器都返回`body`元素 - 除了IE 9,它返回`html`元素.
不确定它是否有帮助,但您可以通过包含属性tabindex ="0"来创建一个元素,例如div接收键盘焦点
`activeElement`实际上不返回focus元素.任何元素都可以有焦点.如果文档具有4'滚动',那么这些div中的0或1可通过箭头键滚动.如果单击一个,则该div将被聚焦.如果你点击所有外部,身体就会聚焦.你怎么知道哪个都是重点?http://jsfiddle.net/rudiedirkx/bC5ke/show/(检查控制台)
对`document.activeElement`的任何访问都应该包含在`try catch`中,因为在某些情况下它可以抛出异常(不仅仅是IE9 AFAIK).见http://bugs.jquery.com/ticket/13393和http://bugs.jqueryui.com/ticket/8443

2> Wookai..:

正如JW所说,至少在与浏览器无关的方式中,你无法找到当前的焦点元素.但如果您的应用程序仅限IE(有些是......),您可以通过以下方式找到它:

document.activeElement

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


FF3也是.这实际上是关于"焦点管理"的HTML5规范的一部分.
现在不能在chrome(15.0 ...)中工作,它返回body.
它适用于当前版本的Chrome和Opera(9.62).在OS X上的Safari 3.2.3中不起作用,但它适用于昨天发布的Safari 4 :)

3> William Denn..:

如果您可以使用jQuery,它现在支持:focus,只需确保您使用的是1.6+版本.

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

$(":focus")

From:如何使用jQuery选择一个关注它的元素


很好,但是jQuery如何做到这一点?document.activeElement?我发现了这个:`return elem === document.activeElement &&(!document.hasFocus || document.hasFocus())&& !!(elem.type || elem.href ||〜〜elem.tabIndex);`

4> Andy E..:

document.activeElement现在是HTML5工作草案规范的一部分,但在某些非主要/移动/旧版浏览器中可能尚不支持它.您可以回退querySelector(如果支持的话).值得一提的是,如果没有元素被聚焦,document.activeElement将返回document.body- 即使浏览器窗口没有焦点.

以下代码将解决此问题,并回过头来querySelector提供更好的支持.

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

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



5> 1j01..:

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.bodydocument.documentElement,这是因为一些浏览器返回的其中之一或null没事的时候集中.

它没有考虑(或者)是否具有tabIndex属性,因此实际上可以集中注意力.如果你正在编写一个库或某些东西,并希望它是健壮的,你应该以某种方式处理它.


这是一个(重型气流)"单线"版本获得聚焦元素,这在概念上更复杂,因为你必须知道短路,你知道,它显然不适合在一条线上,假设你希望它具有可读性.
我不打算推​​荐这个.但是,如果你是一个1337 hax0r,idk ......就在那里.如果您不介意进入某些情况,
也可以删除该|| null部件false.(您仍然可以得到null,如果document.activeElementnull):

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> Nate Whittak..:

document.activeElement如果没有可聚焦元素聚焦,则可以默认为元素.此外,如果元素被聚焦并且浏览器窗口模糊,activeElement则将继续保持聚焦元素.

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



7> Jason..:

我喜欢Joel S使用的方法,但我也喜欢简单的document.activeElement.我使用jQuery并将两者结合起来.不支持的旧浏览器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);


这可以被@William Denniss的`$("*:focus")取代吗?

8> Joel S..:

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

这样,您就可以检查是否元素具有焦点与el.hasFocus()前提是startFocusTracking()被称为给定元素上.



9> DeezCashews..:

JQuery确实支持当前的:focus伪类.如果您在JQuery文档中查找它,请在"选择器"下查看它指向W3C CSS文档.我已经使用Chrome,FF和IE 7+进行了测试.请注意,要在IE中工作,必须存在于html页面上.这是一个假设您已为具有焦点的元素指定了id的示例:

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



10> rplaurindo..:

如果你想获得一个对象,它是实例Element,你必须使用document.activeElement,但如果你想获得一个对象,它是实例Text,你必须使用document.getSelection().focusNode.

我希望有所帮助.


问题是询问目前关注哪个元素.并且`focusNode`也不保证是文本节点.

11> Nathan K..:

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

Some text
Some text
Some text

如果用户关注内部d​​iv,则document.activeElement仍引用外部div.您不能使用document.activeElement来确定哪个内部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;
  }
}


这对`document.activeElement`来说并不是一个问题:内部`
`元素实际上无法获得焦点,因为你可以通过将`:focus`伪类设置为可见的东西来直观地看到(例如:http: //jsfiddle.net/4gasa1t2/1/).你所说的是哪个内部`
包含选择或插入符号,这是一个单独的问题.

12> rjmunro..:

阅读其他答案,并尝试自己,它似乎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
  });
}



13> Arne..:

如果您正在使用jQuery,则可以使用它来查明元素是否处于活动状态:

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

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有