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

2020/09/17 14:31 · javascript ·  · 0评论

我想用JavaScript找出当前关注的元素。我一直在浏览DOM,但尚未找到我需要的东西。有办法做到这一点,怎么做?

我寻找这个的原因:

我正在尝试制作箭头之类的键并enter浏览输入元素表。Tab现在可以使用,但是可以输入,默认情况下,箭头没有显示。我已经设置了关键处理部分,但是现在我需要弄清楚如何在事件处理功能中转移焦点。

使用document.activeElement,所有主要浏览器均支持。

以前,如果您试图找出哪个表单域具有焦点,则无法。要在较旧的浏览器中模拟检测,请向所有字段添加“焦点”事件处理程序,并将最后关注的字段记录在变量中。添加“模糊”处理程序,以在发生模糊事件时清除最后关注的字段的变量。

如果您需要删除,activeElement可以使用模糊;document.activeElement.blur()它将更改activeElementbody

相关链接:

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

document.activeElement

编辑:看来IE毕竟并没有什么错,这是HTML5草案的一部分,并且至少受最新版​​本的Chrome,Safari和Firefox支持。

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

该语句将使您获得当前关注的元素。

$(":focus")

来自:如何使用jQuery选择一个重点关注的元素

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测试

就其本身而言,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,这是因为某些浏览器会返回其中之一,或者null没有重点关注时。

它不考虑<body>(或也许<html>)是否具有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;
});

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

document.activeElement<body>如果没有可聚焦元素,则默认为另外,如果某个元素已聚焦并且浏览器窗口模糊,activeElement将继续保留该聚焦的元素。

如果这两种行为都不理想,请考虑使用基于CSS的方法:document.querySelector( ':focus' )

我喜欢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);

我在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()被称为给定元素上。

到目前为止,JQuery确实支持:focus伪类。如果要在JQuery文档中查找它,请在“选择器”下进行选择,该位置将您指向W3C CSS文档我已经使用Chrome,FF和IE 7+进行了测试。请注意,要使其在IE中运行,<!DOCTYPE...必须在html页面上存在。这是一个示例,假定您已为具有焦点的元素分配了ID:

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

如果要获取作为的实例的对象,则Element必须使用document.activeElement,但是如果要获取作为的实例的对象,则Text必须使用document.getSelection().focusNode

希望对您有所帮助。

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

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

console.log如果打印出整个元素不能帮助您确定元素,则可以随意修改来注销其他内容,以帮助您确定确切的元素。

使用document.activeElement有潜在的问题。考虑:

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

如果用户专注于一个内部div,则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可以为您提供大多数浏览器所需的元素。

如果您使用的浏览器不支持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
  });
}

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

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

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

只需将其放在此处即可给出我最终想到的解决方案。

我创建了一个名为document.activeInputArea的属性,并使用jQuery的HotKeys插件捕获了箭头键,Tab键和Enter键的键盘事件,并且创建了一个事件处理程序以单击输入元素。

然后,每当焦点改变时,我都会调整activeInputArea,因此我可以使用该属性来找出我所在的位置。

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

本文地址:http://javascript.askforanswer.com/woruhezhaochunagedomyuansujuyoujiaodian.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!