您在内容可编辑的光标定位上找到的大多数答案都相当简单,因为它们只适用于具有纯香草文本的输入。一旦在容器中使用html元素,输入的文本就会被拆分成节点,并在树结构中自由分布。
为了设置光标位置,我有这个函数,它循环所有子文本节点在提供的节点内,并设置从初始节点的开始到chars.count字符的范围:
function 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 = createRange(node.childNodes[lp], chars, range);
if (chars.count === 0) {
break;
}
}
}
}
return range;
};
然后,我使用以下函数调用例程:
function setCurrentCursorPosition(chars) {
if (chars >= 0) {
var selection = window.getSelection();
range = createRange(document.getElementById("test").parentNode, { count: chars });
if (range) {
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
}
};
range.collapse(false) 将光标设置为范围的末尾。我已经用最新版本的Chrome,IE,Mozilla和Opera测试了它,它们都可以正常工作。
如果有人感兴趣,我使用以下代码获取当前光标位置:
function isChildOf(node, parentId) {
while (node !== null) {
if (node.id === parentId) {
return true;
}
node = node.parentNode;
}
return false;
};
function getCurrentCursorPosition(parentId) {
var selection = window.getSelection(),
charCount = -1,
node;
if (selection.focusNode) {
if (isChildOf(selection.focusNode, parentId)) {
node = selection.focusNode;
charCount = selection.focusOffset;
while (node) {
if (node.id === parentId) {
break;
}
if (node.previousSibling) {
node = node.previousSibling;
charCount += node.textContent.length;
} else {
node = node.parentNode;
if (node === null) {
break
}
}
}
}
}
return charCount;
};
该代码执行与 set 函数相反的操作 - 它获取当前 window.getSelection().focusNode 和 focusOffset,并向后计数遇到的所有文本字符,直到它命中 id 为 containerId 的父节点。isChildOf 函数只是在运行之前检查所支持的节点是否实际上是所提供 parentId 的子节点。
代码应该可以直接工作而无需更改,但是我刚刚从我开发的jQuery插件中获取了它,因此已经破解了其中的几个 - 如果有什么不起作用,请告诉我!