我有一个简单的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):
const range = document.createRange();
const myDiv = document.getElementById("editable");
range.setStart(myDiv, 5);
range.setEnd(myDiv, 5);
是否可以像这样手动设置插入符号的位置?
在大多数浏览器中,都需要Range和Selection对象。将每个选择边界指定为一个节点,并在该节点中指定偏移量。例如,要将插入符号设置为第二行文本的第五个字符,您可以执行以下操作:
function setCaret()
var el =文档。getElementById(“编辑”)
咖啡壶。
var = window.getSelection()
太阳城setStart (el。childNodes [2], 5)
太阳城崩溃(真正的)。
细胞removeAllRanges()。
细胞addRange(射程)。
的
<div id=“编辑”contenteble =“真”>
文本文本<br>文本文本<br>文本文本<br>
< / div >
<巴顿id=“巴顿”onclick=“setCaret”()巴顿”focus > < - >
IE < 9的工作方式完全不同。如果需要支持这些浏览器,则需要不同的代码。
jsFiddle示例:http://jsfiddle.net/timdown/vXnCM/
我重构了@Liam的答案。我把它放在一个带有静态方法的类中,我让它的函数接收一个元素而不是#id,还有其他一些小调整。
这段代码特别适用于在富文本框中固定光标,例如<div contenteditable="true">。在得到下面的代码之前,我被这个问题困了好几天。
编辑:他的答案和这个答案有一个bug,涉及到按回车键。由于enter不能算作一个字符,所以按下enter键后光标的位置就乱了。如果我能够修复代码,我将更新我的答案。
edit2:为自己省去很多麻烦,确保<div contenteditable=true>为display: inline-block。这修复了一些有关Chrome浏览器把<div>而不是<br>当你按下enter的错误。
如何使用
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();
Code
// 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;
}
}
function set_mouse() {
var as = document.getElementById("editable");
el = as.childNodes[1].childNodes[0]; //goal is to get ('we') id to write (object Text) because it work only in object text
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el, 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
document.getElementById("we").innerHTML = el; // see out put of we id
}
<div id="editable" contenteditable="true">dddddddddddddddddddddddddddd
<p>dd</p>psss
<p>dd</p>
<p>dd</p>
<p>text text text</p>
</div>
<p id='we'></p>
<button onclick="set_mouse()">focus</button>
当你有(p) (span)等高级元素时,将插入符号设置在合适的位置是非常困难的。目标是获取(对象文本):
<div id="editable" contenteditable="true">dddddddddddddddddddddddddddd<p>dd</p>psss<p>dd</p>
<p>dd</p>
<p>text text text</p>
</div>
<p id='we'></p>
<button onclick="set_mouse()">focus</button>
<script>
function set_mouse() {
var as = document.getElementById("editable");
el = as.childNodes[1].childNodes[0];//goal is to get ('we') id to write (object Text) because it work only in object text
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el, 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
document.getElementById("we").innerHTML = el;// see out put of we id
}
</script>