Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获取包含HTML内容的contentEditable区域中的插入符号(光标)位置_Javascript_Wysiwyg_Contenteditable_Getselection - Fatal编程技术网

Javascript 获取包含HTML内容的contentEditable区域中的插入符号(光标)位置

Javascript 获取包含HTML内容的contentEditable区域中的插入符号(光标)位置,javascript,wysiwyg,contenteditable,getselection,Javascript,Wysiwyg,Contenteditable,Getselection,我有contentEditable元素(可以是p,div,…),我想在其中获得插入符号(光标)的位置。我通常可以通过以下代码实现: var position = window.getSelection().getRangeAt(0).startOffset; 当元素只包含文本时,这种方法可以很好地工作。但是当元素包含一些HTML格式时,返回的位置相对于包含的HTML元素中的插入符号位置 假设contentEditable元素的内容如下: AB<b>CD</b>EF A

我有contentEditable元素(可以是p,div,…),我想在其中获得插入符号(光标)的位置。我通常可以通过以下代码实现:

var position = window.getSelection().getRangeAt(0).startOffset;
当元素只包含文本时,这种方法可以很好地工作。但是当元素包含一些HTML格式时,返回的位置相对于包含的HTML元素中的插入符号位置

假设contentEditable元素的内容如下:

AB<b>CD</b>EF
ABCDEF
如果插入符号在
内,比如说在C和D之间,则返回的带有上述代码的位置是1而不是3(从contentEditable元素的内容开始计算)

有人能想出解决办法吗?

更新 我编写了一个更简单的版本,它也适用于IE<9:

旧答案 这实际上比整个文档文本中的字符偏移量更有用:DOM范围的
startOffset
属性(这是
window.getSelection().getRangeAt()
返回的内容)是相对于其
startContainer
属性的偏移量(顺便说一句,它不一定总是一个文本节点)。但是,如果你真的想要一个字符偏移量,这里有一个函数可以做到这一点

下面是一个活生生的例子:

下面是函数:

function getCharacterOffsetWithin(range, node) {
    var treeWalker = document.createTreeWalker(
        node,
        NodeFilter.SHOW_TEXT,
        function(node) {
            var nodeRange = document.createRange();
            nodeRange.selectNode(node);
            return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1 ?
                NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
        },
        false
    );

    var charCount = 0;
    while (treeWalker.nextNode()) {
        charCount += treeWalker.currentNode.length;
    }
    if (range.startContainer.nodeType == 3) {
        charCount += range.startOffset;
    }
    return charCount;
}
函数getCharacterOffsetWithin(范围、节点){ var treeWalker=document.createTreeWalker( 节点, NodeFilter.SHOW_TEXT, 功能(节点){ var noderage=document.createRange(); nodeRange.选择node(节点); 返回节点长度。比较基本点(Range.END\u到\u END,Range)<1? NodeFilter.FILTER\u接受:NodeFilter.FILTER\u拒绝; }, 假的 ); var charCount=0; while(treeWalker.nextNode()){ charCount+=treeWalker.currentNode.length; } if(range.startContainer.nodeType==3){ charCount+=range.startOffset; } 返回字符数; }
如果要插入元素,可以尝试执行以下操作:

// Get range
var range = document.caretRangeFromPoint(event.clientX, event.clientY);
if (range)
  range.insertNode(elementWhichYouWantToAddToContentEditable);

这是一篇非常古老的帖子,但仍然是谷歌搜索的第一批结果之一,因此可能仍然有用。考虑到html标记和换行符,这对我获得正确的位置很有用(在Firefox上测试):


它使用cloneContents功能来获取实际的html,并将documentfragment附加到一个临时div中以获取html长度。

如果您想在可编辑元素中设置字符偏移量,我可以问一下原因吗?可能有更好的方法来实现您的要求。我有自己的WYSIWYG编辑器,它有意地进行操作它与所有普通编辑器略有不同。每个
都启用了内容编辑功能。现在,我试图解决用户只需使用箭头键就可以从一个段落移动到另一个段落的问题。因此,我需要检测段落中插入符号的位置,以便根据按下的箭头键重新定位。感谢您的回答,它看起来很不错d、 但是它有一个小错误。请你尝试修复它,因为我没有运气尝试过。我已经更改了你的代码以内联显示插入符号位置,并且它会对keyup事件作出反应。代码运行良好,但当插入符号位于标记的开始或结束时返回错误的结果。请自己尝试,只需单击contentEditable div并保持pres唱右箭头键移动插入符号。@Frodik:完成。看。我也更新了答案。非常感谢Tim,现在它完美无瑕,正是我所需要的。再次感谢。@Frodik:因为我在其他地方没有提到过这一点,所以我在这里提到:这个答案对IE不起作用是的,我知道。我的网络应用程序不支持IE看起来像
caretRangeFromPoint
是特定于Firefox的;这太可惜了。document.caretRangeFromPoint(x,y)与webkit和document.caretPositionFromPoint(x,y)与Firefox?。Dunno做了这项工作:这对我来说比当前接受的答案(作者的原始版本和更新版本)要好得多,因为其中包含格式化HTML的内容可编辑div。
function getCaretPosition (node) {
    var range = window.getSelection().getRangeAt(0),
        preCaretRange = range.cloneRange(),
        caretPosition,
        tmp = document.createElement("div");

    preCaretRange.selectNodeContents(node);
    preCaretRange.setEnd(range.endContainer, range.endOffset);
    tmp.appendChild(preCaretRange.cloneContents());
    caretPosition = tmp.innerHTML.length;
    return caretPosition;
}