使用JavaScript的focus()函数能否将焦点集中在<div>上?

324

使用JavaScript的focus()函数来将焦点聚焦在<div>标签上,是否可行?

我有一个<div>标签。

<div id="tries">You have 3 tries left</div>
我试图使用以下代码集中在上述
上:
document.getElementById('tries').focus();

但是它不起作用。有人能建议一些东西吗?


4
当你“聚焦”它时,你希望发生什么?Divs不接受输入,所以您是希望闪烁边框,还是闪烁背景高亮等等? - Michael Shimmins
@Michael,是的,我需要那个<div>来吸引用户的注意力... - OM The Eternity
1
可能是哪些HTML元素可以接收焦点?的重复问题。 - Ciro Santilli OurBigBook.com
阅读此内容:https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/focus - Hooman Askari
1
@MichaelShimmins 和其他人,如果你将 contenteditable 设置为 true,<div> 元素可以接受输入。 (这就是我询问的原因) - MattOlivos
2
@MichaelShimmins 如果 div 溢出并显示滚动条,则可以接受输入。当聚焦于带有滚动条的 div 时,箭头键将滚动其内容(而不是其他元素(如 body)的内容)。 - Rory O'Kane
8个回答

622

是的 - 这是可能的。为了做到这一点,您需要为文本框分配一个tabindex...

<div tabindex="0">Hello World</div>
一个tabindex值为0的标签会被放在“页面自然的Tab顺序”中。一个更高的数字将赋予它特定的优先级顺序,其中1是第一位,2是第二位,以此类推。
你也可以给一个tabindex值为-1,这将使div只能通过脚本来聚焦,而不能由用户聚焦。
document.getElementById('test').onclick = function () {
    document.getElementById('scripted').focus();
};
div:focus {
    background-color: Aqua;
}
<div>Element X (not focusable)</div>
<div tabindex="0">Element Y (user or script focusable)</div>
<div tabindex="-1" id="scripted">Element Z (script-only focusable)</div>
<div id="test">Set Focus To Element Z</div>
很明显,如果有一个可以通过脚本聚焦但无法通过其他输入方式聚焦的元素,这是很遗憾的事情(特别是对于只能使用键盘或具有类似约束的用户)。还有一堆标准元素默认情况下就可以被聚焦,并包含语义信息以帮助用户。请明智地利用这些知识。

7
@Michael Shimmins,这使得该元素可以通过focus()方法(以非标准的方式!)获得焦点。 - strager
2
@Olical - 我非常确定这正是我回答中最后一行所说的。如果您认为需要进行编辑,请告诉我。 - Fenton
3
如果不太清楚,给一个元素添加 tabindex 属性可以使其可聚焦,这样就能使用 focus()blur() 方法,然后你可以像这样触发聚焦:document.getElementById('tries').focus(); - pilau
4
嗨,@SteveOwen - 看起来在 Firefox v42 中仍然有效。我已经添加了一段代码片段到这个回答中,这样你就可以运行它进行测试。 - Fenton
12
@SteveOwen 使用 window.location.hash = ... 就是实现这个功能的方式。"focus" 并不意味着 "将元素带入视野",它只是简单地将焦点放在该元素上。 - Fenton
显示剩余14条评论

116
window.location.hash = '#tries';

这将滚动到相关元素, 本质上是 "聚焦" 它。


2
@Casey Chu:在IE中运行良好,但在Firefox中不行,你有什么想法吗? - Haseeb Akhtar
它在某些Chrome版本中无法工作... 然而,@vinoths的解决方案可以解决这个问题。 - Charliemops
1
这个可以运行,但是...如果使用Angular会有问题!! - Carlos Verdes
@CarlosVerdes; Angular 有解决方案吗? - Mac Vicious
6
不回答“焦点”问题,这不应该是正确的答案。就我的情况而言,我想把焦点放在一个“contentEditable” div 上,而你的技巧并没有帮助到我。 - arnaudambro

95

document.getElementById('tries').scrollIntoView() 能够正常工作。 当你的页面使用固定定位时,这比window.location.hash 更好用。


2
请注意,此解决方案在IE、Opera或Safari中无法使用。 - AlecRust
2
我刚在Chrome 65中尝试了一下,但它并没有起作用。覆盖层div滚动到视图中,但焦点仍在背景div中。我知道的唯一可靠的方法是在覆盖层div中使用tabindex属性创建一个可制表元素,并对该元素使用focus()。 - thdoan
@om-the-eternity已经表明他想让div吸引用户的注意,所以他需要的不是实际上聚焦(即使在工作时这样做也是不正确的),而是将其带到屏幕上,这解决了这个问题。 - Omar Vazquez
如果我在Chrome中这样做,它会不停地滚动回到仍然聚焦的输入字段,特别是当页面尚未加载完成时。 - Roger Krueger

82
您可以使用tabindex。
<div tabindex="-1"  id="tries"></div>

tabindex 属性的值可以导致某些有趣的行为。

  • 如果给定了值 "-1",则该元素不能通过 Tab 键聚焦到,但可以使用 element.focus() 方法以编程方式将焦点放在该元素上。
  • 如果给定值 0,则可以通过键盘将焦点聚焦到元素,并进入文档的 Tab 流程。值大于 0 的情况下,创建具有优先级级别,其中 1 是最重要的。

救命稻草,谢谢。在Edge中可以将div设置为焦点,但在Chrome中需要使用这个技巧。被接受的答案很好,但我不想在URL中添加额外的部分。 - Cal
如果您需要进行一些JS DOM操作来处理UI,那么这绝对是最好的答案。它非常方便,可以允许使用onblur来关闭诸如菜单或弹出窗口等元素。 - d0rf47

21
<div id="inner" tabindex="0">
    this div can now have focus and receive keyboard events
</div>

这个只在Chromium/Chrome 46中有效,结合$('#inner').focus();使用。 - TNT

13

document.getElementById('test').onclick = function () {
    document.getElementById('scripted').focus();
};
div:focus {
    background-color: Aqua;
}
<div>Element X (not focusable)</div>
<div tabindex="0">Element Y (user or script focusable)</div>
<div tabindex="-1" id="scripted">Element Z (script-only focusable)</div>
<div id="test">Set Focus To Element Z</div>


3
回答不错,但最好也在你的代码示例中添加一些解释。 - Wilt

3

我想建议类似于Michael Shimmin的东西,但是不要像元素或应用于其上的CSS那样硬编码。

我仅使用jQuery进行add/remove class操作,如果您不想使用jQuery,则只需要替换add/removeClass操作即可。

--Javascript

function highlight(el, durationMs) { 
  el = $(el);
  el.addClass('highlighted');
  setTimeout(function() {
    el.removeClass('highlighted')
  }, durationMs || 1000);
}

highlight(document.getElementById('tries'));

--CSS

#tries {
    border: 1px solid gray;
}

#tries.highlighted {
    border: 3px solid red;
}

1

要使边框闪烁,您可以这样做:

function focusTries() {
    document.getElementById('tries').style.border = 'solid 1px #ff0000;'
    setTimeout ( clearBorder(), 1000 );
}

function clearBorder() {
    document.getElementById('tries').style.border = '';
}

这将使边框变为红色,持续1秒钟,然后再次移除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接