哪些HTML元素可以接收焦点?

我正在寻找一个明确的HTML元素列表,允许采取焦点,即哪些元素将放在焦点,当focus()被调用时?

我正在编写一个jQuery扩展,它可以对可以聚焦的元素进行处理。我希望这个问题的答案能让我明确我的目标元素。

175340 次浏览
没有明确的列表,这取决于浏览器。我们拥有的唯一标准是DOM Level 2 HTML,根据该标准,具有focus()方法的唯一元素是 HTMLInputElementHTMLSelectElementHTMLTextAreaElementHTMLAnchorElement。这显然省略了HTMLButtonElementHTMLAreaElement

今天的浏览器在HTMLElement上定义了focus(),但除非元素是以下情况之一,否则它实际上不会受到关注:

  • htmllanchorelement /HTMLAreaElement带有href
  • htmllinputelement /HTMLSelectElement/HTMLTextAreaElement/HTMLButtonElement,但没有disabled(如果你尝试,IE实际上会给你一个错误),文件上传出于安全原因有不寻常的行为
  • HTMLIFrameElement(尽管聚焦它没有做任何有用的事情)。可能还有其他嵌入元素,我还没有全部测试。
  • 任何带有tabindex的元素

根据浏览器的不同,可能会有其他微妙的例外和附加行为。

这里我有一个基于bobince回答的css选择器来选择任何可聚焦的HTML元素:

  a[href]:not([tabindex='-1']),
area[href]:not([tabindex='-1']),
input:not([disabled]):not([tabindex='-1']),
select:not([disabled]):not([tabindex='-1']),
textarea:not([disabled]):not([tabindex='-1']),
button:not([disabled]):not([tabindex='-1']),
iframe:not([tabindex='-1']),
[tabindex]:not([tabindex='-1']),
[contentEditable=true]:not([tabindex='-1'])
{
/* your CSS for focusable elements goes here */
}

或者在SASS中更漂亮一点:

a[href],
area[href],
input:not([disabled]),
select:not([disabled]),
textarea:not([disabled]),
button:not([disabled]),
iframe,
[tabindex],
[contentEditable=true]
{
&:not([tabindex='-1'])
{
/* your SCSS for focusable elements goes here */
}
}

我把它作为一个答案,因为那是,我正在寻找的,当谷歌重定向我到这个Stackoverflow问题。

还有一个选择器,它是可聚焦的:

[contentEditable=true]

然而,这种方法很少使用。

$focusable:
'a[href]',
'area[href]',
'button',
'details',
'input',
'iframe',
'select',
'textarea',


// these are actually case sensitive but i'm not listing out all the possible variants
'[contentEditable=""]',
'[contentEditable="true"]',
'[contentEditable="TRUE"]',


'[tabindex]:not([tabindex^="-"])',
':not([disabled])';

我正在创建一个所有可聚焦元素的SCSS列表,我认为这可能会帮助一些人,因为这个问题的谷歌排名。

有几件事需要注意:

  • 我将:not([tabindex="-1"])改为:not([tabindex^="-"]),因为以某种方式生成-2是完全合理的。安全总比后悔好,对吧?
  • :not([tabindex^="-"])添加到所有其他可聚焦选择器中是完全没有意义的。当使用[tabindex]:not([tabindex^="-"])时,它已经包含了所有你将用:not来否定的元素!
  • 我包含了:not([disabled]),因为禁用的元素可以从来没有是可聚焦的。所以把它加到每一个元素上是没有用的。

ally.js可访问性库提供了一个非官方的、基于测试的列表:

https://allyjs.io/data-tables/focusable.html

(注意:他们的页面没有说明多久进行一次测试。)

也许这个可以帮到你:

function focus(el){
el.focus();
return el==document.activeElement;
}

返回值:true =成功,false =失败

< p >雷夫: https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus < / p >

有一种更优雅的方式来处理这个问题:

像下面的样例一样扩展元素原型。 然后你可以这样使用:

element.isFocusable()

*返回真正的如果"element"是可聚焦的,如果不是

/**
* Determining if an element can be focused on
* @return   {Boolean}
*/
HTMLElement.prototype.isFocusable = function () {
var current = document.activeElement
if (current === this) return true
var protectEvent = (e) => e.stopImmediatePropagation()
this.addEventListener("focus", protectEvent, true)
this.addEventListener("blur", protectEvent, true)
this.focus({preventScroll:true})
var result = document.activeElement === this
this.blur()
if (current) current.focus({preventScroll:true})
this.removeEventListener("focus", protectEvent, true)
this.removeEventListener("blur", protectEvent, true)
return result
}


// A SIMPLE TEST
console.log(document.querySelector('a').isFocusable())
console.log(document.querySelector('a[href]').isFocusable())
<a>Not focusable</a>
<a href="#">Focusable</a>