86

我有一个<div contenteditable=true>我通过所见即所得定义一些元素的地方。例如<p><h1>等。我想直接将重点放在其中一个元素上。

例如在<p id="p_test">. 但似乎该focus()功能不适用于<div>元素,<p>元素......

在我的情况下,是否有另一种方法来定义焦点?

4

9 回答 9

76

旧帖子,但没有一个解决方案对我有用。不过我最终想通了:

var div = document.getElementById('contenteditablediv');
setTimeout(function() {
    div.focus();
}, 0);
于 2016-05-11T12:03:38.947 回答
40

在现代浏览器中,您可以使用:

var p = document.getElementById('contentEditableElementId'),
    s = window.getSelection(),
    r = document.createRange();
r.setStart(p, 0);
r.setEnd(p, 0);
s.removeAllRanges();
s.addRange(r);

但是如果你的元素是空的,我会遇到一些奇怪的问题,所以对于空元素你可以这样做:

var p = document.getElementById('contentEditableElementId'),
    s = window.getSelection(),
    r = document.createRange();
p.innerHTML = '\u00a0';
r.selectNodeContents(p);
s.removeAllRanges();
s.addRange(r);
document.execCommand('delete', false, null);

删除 nbsp 后光标停留在 p 元素内

PS只是普通的空间对我不起作用

于 2013-05-31T18:49:52.500 回答
32

我注意到 jQuery focus() 不适用于宽度和高度为 0 的 contenteditable DIV。我将其替换为 .get(0).focus() - 本机 javascript 焦点方法 - 它可以工作。

于 2013-02-05T05:56:24.813 回答
10

很多时候,如果你不能调用.focus()一个元素,那是因为 tabIndex 是-1,这意味着当你按 tab 导航时,tab 键不能集中在它上面。

将 tabIndex 更改为 >= 0 将使您专注于元素。如果您需要动态执行此操作,您只需在事件侦听器中将 tabindex >= 0 添加到您的元素。

于 2018-07-02T04:08:55.330 回答
7

你可以试试这个代码,它可以自动聚焦在你最后一个插入位置。

let p = document.getElementById('contenteditablediv')
let s = window.getSelection()
let r = document.createRange()
r.setStart(p, p.childElementCount)
r.setEnd(p, p.childElementCount)
s.removeAllRanges()
s.addRange(r)
于 2017-03-04T17:08:17.850 回答
5

在@Surmon answer的基础上进一步发展。如果您希望在文本中的最后一个字母/数字而不是最后一个插入位置之后自动聚焦(如果子节点包含在块类型标签而不是纯文本中,最后一个插入位置会将光标移动到新行)然后应用这个小修改:

r.setStart(p.lastChild, 1);
r.setEnd(p.lastChild, 1);

这是一个扩展函数,它检查编辑器/元素是否有任何子节点,并根据情况在末尾相应地设置光标:

let p = document.getElementById('contenteditablediv');
p.focus();  // alternatively use setTimeout(() => { p.focus(); }, 0);
// this is enough to focus an empty element (at least in Chrome)

if (p.hasChildNodes()) {  // if the element is not empty
  let s = window.getSelection();
  let r = document.createRange();
  let e = p.childElementCount > 0 ? p.lastChild : p;  
  r.setStart(e, 1); 
  r.setEnd(e, 1);    
  s.removeAllRanges();
  s.addRange(r);
} 
于 2019-12-21T15:55:21.023 回答
4

还有一件事要检查:如果您打开了浏览器的控制台窗口,请确保在加载页面时控制台没有焦点,否则页面上的元素将无法按预期获得焦点。

这似乎也意味着您无法document.querySelector('#your-elem').focus()在控制台中运行(在 Mac 上使用 Chrome、Safari 和 Firefox 进行了尝试,2020 年 8 月)。

于 2020-08-08T14:19:16.610 回答
3

如果有人使用管理元素的MediumEditor 偶然contenteditable发现这个问题,以下对我有用:

editor.selectElement(editorDOMNode);
  1. editor是 的一个实例MediumEditor
  2. editorDOMNode是对实际contenteditableDOM 节点的引用。
  3. 也可以关注编辑器中的特定子节点,如下所示:

    editor.selectElement(editorDOMNode.childNodes[0]);
    
于 2016-03-02T10:14:46.120 回答
-10

将“click”事件处理程序绑定到 contenteditable div 中的所有元素,并在单击时更改类/样式(即向元素添加“focused”类);

您可以通过添加诸如彩色边框或内部框阴影之类的样式来向用户识别哪个元素具有焦点。然后,当您想访问 jQuery 脚本中的焦点元素时,只需执行以下操作:

var focused = $('.focused');

于 2012-04-20T20:05:04.897 回答