我有一个简单的HTML示例:
<div id="editable" contenteditable="true">
text text text<br>
text text text<br>
text text text<br>
</div>
<button id="button">focus</button>
我想要简单的事情-当我点击按钮时,我想把插入符号(光标)放在可编辑div中的特定位置。在网上搜索,我有这个JS附加到按钮点击,但它不工作(FF,Chrome):
var range = document.createRange();
var myDiv = document.getElementById("editable");
range.setStart(myDiv, 5);
range.setEnd(myDiv, 5);
可以像这样手动设置插入符号的位置吗?
发布于 2011-06-06 16:33:00
在大多数浏览器中,您需要Range
和Selection
对象。您可以将每个选择边界指定为节点和该节点内的偏移。例如,要将插入符号设置为第二行文本的第五个字符,请执行以下操作:
function setCaret() {
var el = document.getElementById("editable")
var range = document.createRange()
var sel = window.getSelection()
range.setStart(el.childNodes[2], 5)
range.collapse(true)
sel.removeAllRanges()
sel.addRange(range)
}
<div id="editable" contenteditable="true">
text text text<br>text text text<br>text text text<br>
</div>
<button id="button" onclick="setCaret()">focus</button>
IE <9的工作方式完全不同。如果你需要支持这些浏览器,你需要不同的代码。
jsFiddle示例:http://jsfiddle.net/timdown/vXnCM/
发布于 2020-07-03 00:26:41
我重构了@Liam的答案。我把它放在一个带有静态方法的类中,我让它的函数接收一个元素而不是#id,并做了一些其他的小调整。
此代码特别适用于修复您可能使用<div contenteditable="true">
创建的富文本框中的光标。在达到下面的代码之前,我被困在这里好几天了。
编辑:他的答案和这个答案都有一个错误,涉及到按enter键。由于enter不算字符,因此在按enter后光标位置会变得混乱。如果我能够修复代码,我会更新我的答案。
edit2:省去了很多麻烦,并确保你的<div contenteditable=true>
是display: inline-block
。这修复了一些与Chrome在按enter键时使用<div>
而不是<br>
相关的错误。
如何使用
let richText = document.getElementById('rich-text');
let offset = Cursor.getCurrentCursorPosition(richText);
// insert code here that does stuff to the innerHTML, such as adding/removing <span> tags
Cursor.setCurrentCursorPosition(offset, richText);
richText.focus();
代码
// Credit to Liam (Stack Overflow)
// https://stackoverflow.com/a/41034697/3480193
class Cursor {
static getCurrentCursorPosition(parentElement) {
var selection = window.getSelection(),
charCount = -1,
node;
if (selection.focusNode) {
if (Cursor._isChildOf(selection.focusNode, parentElement)) {
node = selection.focusNode;
charCount = selection.focusOffset;
while (node) {
if (node === parentElement) {
break;
}
if (node.previousSibling) {
node = node.previousSibling;
charCount += node.textContent.length;
} else {
node = node.parentNode;
if (node === null) {
break;
}
}
}
}
}
return charCount;
}
static setCurrentCursorPosition(chars, element) {
if (chars >= 0) {
var selection = window.getSelection();
let range = Cursor._createRange(element, { count: chars });
if (range) {
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
}
}
static _createRange(node, chars, range) {
if (!range) {
range = document.createRange()
range.selectNode(node);
range.setStart(node, 0);
}
if (chars.count === 0) {
range.setEnd(node, chars.count);
} else if (node && chars.count >0) {
if (node.nodeType === Node.TEXT_NODE) {
if (node.textContent.length < chars.count) {
chars.count -= node.textContent.length;
} else {
range.setEnd(node, chars.count);
chars.count = 0;
}
} else {
for (var lp = 0; lp < node.childNodes.length; lp++) {
range = Cursor._createRange(node.childNodes[lp], chars, range);
if (chars.count === 0) {
break;
}
}
}
}
return range;
}
static _isChildOf(node, parentElement) {
while (node !== null) {
if (node === parentElement) {
return true;
}
node = node.parentNode;
}
return false;
}
}
发布于 2018-10-09 15:52:55
我正在写一个语法高亮笔(和基本的代码编辑器),我需要知道如何自动键入单引号字符并将插入符号移回(就像现在的许多代码编辑器一样)。
这是我的解决方案的一小段,感谢这个帖子、MDN文档和许多moz控制台观看的帮助。
//onKeyPress event
if (evt.key === "\"") {
let sel = window.getSelection();
let offset = sel.focusOffset;
let focus = sel.focusNode;
focus.textContent += "\""; //setting div's innerText directly creates new
//nodes, which invalidate our selections, so we modify the focusNode directly
let range = document.createRange();
range.selectNode(focus);
range.setStart(focus, offset);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
//end onKeyPress event
这是在一个可编辑的div元素中
我把这个留在这里作为感谢,因为我意识到已经有了一个公认的答案。
https://stackoverflow.com/questions/6249095
复制相似问题