代码之家  ›  专栏  ›  技术社区  ›  user1893354

获取所选文本开始和结束的字符偏移量

  •  0
  • user1893354  · 技术社区  · 6 年前

    对于给定的字符串,我可以使用

    var text = window.getSelection().toString();
    

    我正在尝试获取所选文本的字符偏移量。我试过了

    window.getSelection().getRangeAt(0).startOffset
    

    用于选定内容开头的字符偏移量和

    window.getSelection().getRangeAt(0).endOffset
    

    但是,对于所选内容结尾的字符偏移量,这会产生不正确的结果。

    例如,对于示例字符串

    lskdjfldjf sdlkjfsdl jflsdk fjlksdjf lksdjfl sdjfl sdjflsdkjfskl
    

    当我选择第一个词(即到第一个空格为止的所有内容)时,根据上述方法,开始偏移量为41,结束偏移量为51。正确的偏移应该是0和10。我觉得我走得有点对,因为偏移量之间的差异是正确的,但它只是错误的值。有没有什么方法可以通过编程的方式从偏移量中减去我应该得到的值来获得正确的偏移量(在本例中是41)?还是有更好的方法来获取所选文本的偏移量?

    更新:

    这是发生这种情况的较大的HTML块

      <div class="panel panel-default">
                  <div class="panel-heading"><strong>Example {{i + 1}} of {{examples.length}}</strong></div>
                          <div class="panel-body">
                                <div (mouseup)="showSelectedText(i)">
                                                {{example.labelled}}
                                </div>
                           </div>
        </div>
    

    这是一个Angular2应用程序。函数的位置 showSelectedText() 包含选择逻辑

    2 回复  |  直到 6 年前
        1
  •  2
  •   Vignesh Raja    6 年前

    这是因为HTML结构。

    var elem = document.getElementById("text");
    
    document.addEventListener("mouseup",function(){
        if(window.getSelection)
        {
            var text = window.getSelection().toString();
            var range = window.getSelection().getRangeAt(0);
            console.log(range.startContainer.textContent,
                        range.startOffset,
                        range.endOffset)
        }
    },false);
    <div>
    You made me a, you made me a Believer!
    </div>
    <div>You made me a, you made me a Believer!</div>
    <div>You made me a, you made me a Believer!
    </div>

    观察下面上面代码段的HTML结构,

    HTML structure of the example snippet

    现在在上面的输出中选择一行。在选择时,

    1. 第一行 -索引以5开头-不带标记的文本内容附加到 body 标记为 newline 性格和A tab (默认为4个空格),默认为 startindex 5 .
    2. 第二行 -索引以1开头-根据编写的HTML代码段添加了一个新行字符。
    3. 第三行 -正常行为。
    4. 第四行 -索引以大于实际索引的值1结尾-附加 换行符 结尾的字符。

    document.addEventListener("mouseup",function(){
        if(window.getSelection)
        {
            var selectedtext = window.getSelection().toString();
            var range = window.getSelection().getRangeAt(0);
            var content = range.startContainer.textContent;
            content = content.replace(/(?:\r\n|\r|\n)/g, '');
            if(range.startContainer.parentElement.tagName=="BODY")
            {
                content = content.replace(/^\s*|\s*$/, '');
            }
            console.log(content, content.indexOf(selectedtext), content.indexOf(selectedtext)+selectedtext.length)
        }
    },false);
    You made me a, you made me a Believer!
    
    <div>
    You made me a, you made me a Believer!
    </div>
    <div>You made me a, you made me a Believer!</div>
    <div>You made me a, you made me a Believer!
    </div>

    上面的截图非常有效,只在选择单个元素中的内容时有效。如果在多个元素中选择,则需要修改实现。

        2
  •  0
  •   Damodhar    6 年前

    在下面使用的函数将根据文档返回新的范围。

    restoreSelection = function(savedSel,doc) {
    var charIndex = 0;
    var range = doc.createRange();
    range.setStart(doc.body, 0);
    range.collapse(true);
    var nodeStack = [doc.body],
        node, foundStart = false,
        stop = false;
    savedSel.end = savedSel.end;
    while (!stop && (node = nodeStack.pop())) {
        if (node.nodeType == 3) {
            var nextCharIndex = charIndex + node.length;
            if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
                range.setStart(node, savedSel.start - charIndex);
                foundStart = true;
            }
            if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
                range.setEnd(node, savedSel.end - charIndex);
                stop = true;
            }
            charIndex = nextCharIndex;
        } else {
            var i = node.childNodes.length;
            while (i--) {
                nodeStack.push(node.childNodes[i]);
            }
        }
    }
    return range;
    

    }

    savedsel:您的范围和文档将

    此函数将返回带有偏移量的新范围