首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >获取包含contentEditable内容的区域中的插入符号(光标)位置

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

Stack Overflow用户
提问于 2011-01-22 20:41:05
回答 3查看 74.2K关注 0票数 60

我有contentEditable元素(可以是p,div,...)我想得到插入符号(光标)在其中的位置。我通常可以用下面这段代码来实现:

代码语言:javascript
复制
var position = window.getSelection().getRangeAt(0).startOffset;

当元素只包含文本时,这可以很好地工作。但是当元素包含一些HTML格式时,返回的位置是相对于包含的HTML元素中的插入符号位置的。

让我们假设contentEditable元素的内容如下:

代码语言:javascript
复制
AB<b>CD</b>EF

如果插入符号在<b></b>中,假设在C和D之间,上面代码返回的位置是1而不是3(从contentEditable元素内容的开头开始计算)

有人能想出解决这个问题的办法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-23 05:03:04

更新

我已经写了一个更简单的版本,也可以在IE <9中工作:

https://stackoverflow.com/a/4812022/96100

老答案

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

这里有一个活的例子:http://jsfiddle.net/timdown/2YcaX/

下面是函数:

代码语言:javascript
复制
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;
}
票数 54
EN

Stack Overflow用户

发布于 2017-10-24 12:43:06

这是一个非常老的帖子,但仍然是谷歌搜索的第一个结果之一,所以可能仍然有用。考虑到html标签和换行符(在Firefox上测试),这对我来说是有效的:

代码语言:javascript
复制
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;
}

它使用cloneContents功能来获得实际的html,并将文档片段附加到临时div以获得html长度。

票数 15
EN

Stack Overflow用户

发布于 2014-06-18 01:59:41

如果你想插入元素,你可以尝试这样做:

代码语言:javascript
复制
// Get range
var range = document.caretRangeFromPoint(event.clientX, event.clientY);
if (range)
  range.insertNode(elementWhichYouWantToAddToContentEditable);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4767848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档