将焦点设置在 div contenteditable 元素上
Posted
技术标签:
【中文标题】将焦点设置在 div contenteditable 元素上【英文标题】:Set focus on div contenteditable element 【发布时间】:2011-01-24 04:40:44 【问题描述】:我有一个<div contenteditable=true>
,我通过所见即所得的方式定义了一些元素。例如<p>
、<h1>
等。我想直接将重点放在其中一个元素上。
例如<p id="p_test">
。但似乎focus()
函数不适用于<div>
元素、<p>
元素...
在我的情况下,是否有另一种方法来定义焦点?
【问题讨论】:
你不能聚焦一个 div 或 p,因为它没有任何动作,你想聚焦什么? @NickCraver 该问题提到其内容可编辑,这意味着您可以键入和编辑它等完全有效的问题imo @Blowsie 我相信最初的问题没有提到 contenteditable 功能。 Nick Craver 对其进行了编辑并理解了它。重点。var r=new Range(), sel=getSelection(); r.setStart(div.lastChild, div.lastChild.length||1);sel.removeAllRanges();sel.addRange(r)
【参考方案1】:
将“click”事件处理程序绑定到 contenteditable div 中的所有元素,并在单击时更改类/样式(即向元素添加“focused”类);
您可以通过添加彩色边框或内框阴影等样式向用户识别哪个元素具有焦点。然后,当您想要访问 jQuery 脚本中的焦点元素时,只需执行以下操作:
var focused = $('.focused');
【讨论】:
他问的是实际将用户的插入符号移动到元素上,而不仅仅是设置选定元素的样式。 这没有任何帮助。【参考方案2】:我注意到 jQuery focus() 不适用于宽度和高度为 0 的内容可编辑 DIV。我将其替换为 .get(0).focus() - 本机 javascript 焦点方法 - 它可以工作。
【讨论】:
哪个浏览器?它似乎在 Safari 中不起作用,但 Firefox 和 Chrome 处理得很好。 哪一部分?选择元素和 focus() 例如 document.getElementById("#mydiv").focus()【参考方案3】:在现代浏览器中,您可以使用:
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元素内
附:普通的空间不适合我
【讨论】:
你的例子中的变量 p 是什么? @BT 我认为它是根 P 元素,尽管他应该澄清它而不留下怀疑的空间。 在众多建议的解决方案中,这是唯一对我有用的解决方案,让我可以将焦点放在 jquery 对话框中的内容可编辑 div 上。 很好的解决方案.. 谢谢 :) 我将r.setStart(p, 1)
和r.setEnd(p, 1)
中的0 更改为1,以将光标放在contenteditable
div 的末尾。我不知道为什么会这样,但确实如此。谢谢!【参考方案4】:
如果有人使用管理contenteditable
元素的MediumEditor 偶然发现这个问题,以下对我有用:
editor.selectElement(editorDOMNode);
editor
是 MediumEditor
的一个实例。
editorDOMNode
是对实际 contenteditable
DOM 节点的引用。
也可以在编辑器中关注特定的子节点,如下所示:
editor.selectElement(editorDOMNode.childNodes[0]);
【讨论】:
【参考方案5】:旧帖子,但没有一个解决方案对我有用。不过我最终想通了:
var div = document.getElementById('contenteditablediv');
setTimeout(function()
div.focus();
, 0);
【讨论】:
不知道为什么,这完全有效!!!将 .focus() 逻辑包装在 setTimeout 中就可以了!谢谢! 不错!有些事情需要回到调度程序才能正确操作。浏览器很奇怪。谢谢! 我只在将代码放入其他元素的 onClick 处理程序时遇到过这种情况。我的猜测是存在竞争条件:单击按钮-> onClick 处理程序聚焦某些元素-> 按钮获得焦点。放置 setTimeout 将推迟代码,使其保持焦点。 我来自未来,这也是未来的工作【参考方案6】:你可以试试这个代码,它可以自动聚焦在你最后插入的位置。
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)
【讨论】:
谢谢,您上面的部分相同答案对我不起作用,我需要添加p.childElementCount
而不是您所写的1
。【参考方案7】:
很多时候如果你不能在一个元素上调用.focus()
,那是因为tabIndex是-1,这意味着当你按tab导航时tab键不能聚焦在它上面。
将 tabIndex 更改为 >= 0 将使您专注于元素。如果您需要动态执行此操作,只需在事件侦听器中将 tabindex >= 0 添加到您的元素。
【讨论】:
这应该是批准的答案。 "除非它具有 tabindex 属性,否则您不能在元素上调用 .focus() 方法"【参考方案8】:在@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);
【讨论】:
【参考方案9】:还有一点需要检查:如果您打开了浏览器的控制台窗口,请确保在您加载页面时控制台没有焦点,否则页面上的元素将无法按预期获得焦点。
这似乎也意味着您无法在控制台中运行 document.querySelector('#your-elem').focus()
(在 Mac 上使用 Chrome、Safari 和 Firefox 进行了尝试,2020 年 8 月)。
【讨论】:
救命稻草!在控制台中什么也没做,但在实际代码中尝试此操作时:document.querySelector('.pell-content').focus();
对于 Pell RTE 来说效果很好。疯了,谢谢!以上是关于将焦点设置在 div contenteditable 元素上的主要内容,如果未能解决你的问题,请参考以下文章
div设置contenteditable="true",即可编辑,我想做一个按钮,点击它之后,焦点处就自动出现一个可编辑的