哪些 HTML 元素可以获得焦点?

问题描述 投票:0回答:7

我正在寻找允许获得焦点的 HTML 元素的明确列表,即当对它们调用

focus()
时哪些元素将成为焦点?

我正在编写一个 jQuery 扩展,它适用于可以成为焦点的元素。我希望这个问题的答案能让我具体说明我的目标元素。

html focus
7个回答
404
投票

没有明确的列表,这取决于浏览器。我们唯一的标准是 DOM Level 2 HTML,根据该标准,唯一具有

focus()
方法的元素是
HTMLInputElement
HTMLSelectElement
HTMLTextAreaElement
HTMLAnchorElement
。这特别省略了
HTMLButtonElement
HTMLAreaElement

当今的浏览器在 HTMLElement 上定义

focus()
,但元素实际上不会获得焦点,除非它是以下之一:

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

根据浏览器的不同,此行为可能还有其他细微的异常和添加。


54
投票

这里我有一个基于 bobinceanswer 的 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]

但是,这种方法很少使用。


14
投票
$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])
    ,因为禁用的元素永远无法成为焦点。所以再次将其添加到每个元素中是没有用的。

11
投票
ally.js

辅助功能库在此处提供了一个非官方的、基于测试的列表:

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

(注意:他们的页面没有说明测试执行的频率。)


7
投票

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


2
投票

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

element.isFocusable()

*如果“element”可聚焦则返回 
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>


0
投票

function isFocusable(el) { const cs = window.getComputedStyle(el, null); if (cs.getPropertyValue('visibility') == 'hidden' || cs.getPropertyValue('display') == 'none') return false; const natively = 'a[href], area[href], details, iframe, :is(button, input, select, textarea)'; if (el.matches(natively) || (el.hasAttribute('tabindex') && parseInt(el.getAttribute('tabindex')) >= 0) || el.isContentEditable) return true; return false; }
*:focus {
    outline: none !important;
    border: 4px solid red;
    box-shadow: 0 0 10px #FF5722;
}
<a id="e1" tabindex="0" role="button" aria-pressed="false">TOGGLE</a>

<span id="not-focusable">NOT FOCUSABLE</span>

<span id="e3" role="button">ACTION</span>

<button id="e4" aria-pressed="false">REAL BUTTON TOGGLE</button>

<button>REAL BUTTON ACTION</button>

<script>
const log = (ev) => {console.log('Focusable?', ev.target, isFocusable(ev.target) )}


document.getElementById('e1').addEventListener('click',  log)
document.getElementById('not-focusable').addEventListener('click',  log)
document.getElementById('e3').addEventListener('click',  log)
document.getElementById('e4').addEventListener('click',  log)

</script>

© www.soinside.com 2019 - 2024. All rights reserved.