我有以下代码片段将插入符号设置为给定的索引index
var el = $("#subjectMessage"), index = 9 ;
var range = rangy.createRange();
range.setStart(el[0].childNodes[0], index);
range.collapse(true);
var sel = rangy.getSelection();
sel.setSingleRange(range);
当我将输入元素添加到contentEditable div
时会出现问题,我不能再将插入符号设置在所需的位置了。
我想将这些输入视为div中的一个位置(就好像它们只是一个字符一样)。
除此之外,我还需要类似的代码来替换此contentEditable div
中的选择,并使用我自己的一些文本,并且我并不熟悉( at all )与rangy一起了解如何使这项工作......
非常欢迎所有帮助!
这是你可以玩的小提琴:
答案 0 :(得分:7)
Rangy的Selection和Range API是标准DOM Selection和Range API的超集,因此适用于MDN(Range,Selection等地方的文档。
您遇到的问题是范围边界表示为包含DOM节点内的偏移量。例如,在下面的HTML中,插入符号表示为管道符:
<p>Foo<br>b|ar</p>
...插入符号范围的起点和终点边界相同,并在文本节点“bar”中设置为偏移1。
如果要将位置设置为<p>
元素的文本内容中的偏移量,则需要进行一些DOM遍历。我基于another answer of mine编写了一个这样的实现。这是天真的实现:它没有考虑任何可能被隐藏的文本(例如,通过CSS或通过在一个或元素内部),并且可能有浏览器差异(IE与其他所有内容)有换行符,并且需要没有折叠空格的帐户(例如2个或更多连续的空格字符折叠到页面上的一个可见空间)。这是一个棘手的事情,这是正确的,这就是为什么我一般不会推荐它。我打算为Rangy写一个基于文本的模块来处理所有这些,但我还没有开始。
代码:
function setCaretCharIndex(containerEl, index) {
var charIndex = 0, stop = {};
function traverseNodes(node) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (index >= charIndex && index <= nextCharIndex) {
rangy.getSelection().collapse(node, index - charIndex);
throw stop;
}
charIndex = nextCharIndex;
}
// Count an empty element as a single character. The list below may not be exhaustive.
else if (node.nodeType == 1
&& /^(input|br|img|col|area|link|meta|link|param|base)$/i.test(node.nodeName)) {
charIndex += 1;
} else {
var child = node.firstChild;
while (child) {
traverseNodes(child);
child = child.nextSibling;
}
}
}
try {
traverseNodes(containerEl);
} catch (ex) {
if (ex != stop) {
throw ex;
}
}
}