【发布时间】:2010-12-08 15:37:54
【问题描述】:
我正在寻找允许获得焦点的 HTML 元素的明确列表,即当调用 focus() 时哪些元素将成为焦点?
我正在编写一个 jQuery 扩展,它适用于可以聚焦的元素。我希望这个问题的答案能让我具体了解我所针对的元素。
【问题讨论】:
我正在寻找允许获得焦点的 HTML 元素的明确列表,即当调用 focus() 时哪些元素将成为焦点?
我正在编写一个 jQuery 扩展,它适用于可以聚焦的元素。我希望这个问题的答案能让我具体了解我所针对的元素。
【问题讨论】:
没有一个明确的列表,这取决于浏览器。我们拥有的唯一标准是DOM Level 2 HTML,根据该标准,唯一具有focus() 方法的元素是
HTMLInputElement、HTMLSelectElement、HTMLTextAreaElement 和 HTMLAnchorElement。这明显省略了HTMLButtonElement 和HTMLAreaElement。
今天的浏览器在 HTMLElement 上定义 focus(),但一个元素实际上不会获得焦点,除非它是以下之一:
disabled(如果您尝试,IE 实际上会给您一个错误),并且出于安全原因,文件上传有异常行为tabindex 的元素
根据浏览器的不同,此行为可能还有其他细微的例外和补充。
【讨论】:
element.isContentEditable === true 的元素也是可聚焦的。请注意,IE -10 (11+?) 可以使用显示块或表格(div、span 等)聚焦任何元素。
这里我有一个基于 bobince 的 answer 的 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 */
}
}
我已将其添加为答案,因为当 Google 将我重定向到这个 Stackoverflow 问题时,我正在寻找它。
编辑:还有一个选择器,它是可聚焦的:
[contentEditable=true]
但是,这很少使用。
【讨论】:
<a href="foo.html">Bar</a> 肯定是可聚焦的,因为它是具有href 属性的a 元素。但是您的选择器不包含它。
tabindex="-1" 确实 not 使元素无法聚焦,只是无法通过 Tab 键聚焦。它仍然可以通过单击它或使用HTMLElement.focus() 以编程方式获得焦点;任何其他负数相同。见:developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/…
input:not([type="hidden"]),除非您希望选择器聚焦在浏览器默认隐藏的视觉和屏幕阅读器的元素
$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 列表,我认为这可能会对某人有所帮助,因为这个问题的 Google 排名。
需要注意的几点:
:not([tabindex="-1"]) 更改为:not([tabindex^="-"]),因为以某种方式生成-2 是完全合理的。安全总比后悔好,对吧?:not([tabindex^="-"]) 添加到所有其他可聚焦选择器是完全没有意义的。使用[tabindex]:not([tabindex^="-"]) 时,它已经包含了您将用:not 否定的所有元素!:not([disabled]),因为禁用的元素永远无法聚焦。所以再一次将它添加到每个元素中是没有用的。【讨论】:
:not([disabled]) 的部分是错误的。不相信我?做一个document.querySelectorAll(':not([disabled])') 看看会发生什么。未禁用意味着您想要所有启用的元素。
:not([tabindex^="-"]的部分。证明:在您的控制台中尝试这一行:document.querySelectorAll('a, [tabindex]:not([tabindex="-1"]')[0] 它将选择一个节点,例如<a href="shouldnt-be-focused" tabindex="-1">nope</a> 对于它的价值,我认为这来自于这些选择器由“或”而不是“和”连接的误解,因此一旦遇到 标签,它就会满足选择器
ally.js 可访问性库在此处提供了一个非官方的、基于测试的列表:
https://allyjs.io/data-tables/focusable.html
(注意:他们的页面没有说明执行测试的频率。)
【讨论】:
也许这个可以帮助:
function focus(el){
el.focus();
return el==document.activeElement;
}
返回值:true = 成功,false = 失败
参考: https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
【讨论】:
有一种更优雅的方式来处理这个问题:
像下面的示例一样扩展元素原型。 然后你可以像这样使用它:
element.isFocusable()
*如果“元素”是可聚焦的,则返回 true,否则返回 false。
/**
* 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>
【讨论】: