为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

慕仰0522570 2019-09-21 14:27:33

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


var position = window.getSelection().getRangeAt(0).startOffset;

当元素仅包含文本时,这可以正常工作。但是,当元素包含某些HTML格式时,返回的位置将相对于所包含HTML元素内的插入符号位置。


假设contentEditable元素的内容是这样的:


AB<b>CD</b>EF

如果插入符在inside <b></b>,比如说在C和D之间,则上面代码返回的位置是1而不是3(从contentEditable元素内容的开头算起)


有人可以提出解决方案吗?


查看完整描述

3 回答

?
ABOUTYOU

UPDATE

我已经编写了一个更简单的版本,该版本也可以在IE <9中使用:


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


旧答案

实际上,这比整个文档文本中的字符偏移量更有用:startOffsetDOM Range 的属性(window.getSelection().getRangeAt()返回的内容)是相对于其startContainer属性的偏移量(不一定是文本节点)方式)。但是,如果您确实想要字符偏移量,可以使用以下函数来实现。


这是一个实时示例:http : //jsfiddle.net/timdown/2YcaX/


功能如下:


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;

}


查看完整回答
反对 回复 2019-09-21
?
湖上湖

这是一篇非常古老的文章,但仍然是在Google上搜索的第一批结果之一,因此也许仍然有用。考虑到html标记和换行符,这对我来说也能找到正确的位置(在Firefox上测试):


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,并将documentfragment附加到临时div上以获取html的长度。



查看完整回答
反对 回复 2019-09-21
?
jeck猫

如果要插入元素,则可以尝试执行以下操作:


// Get range

var range = document.caretRangeFromPoint(event.clientX, event.clientY);

if (range)

  range.insertNode(elementWhichYouWantToAddToContentEditable);


查看完整回答
反对 回复 2019-09-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信