获取所选文本开头和结尾的字符偏移量

时间:2018-07-11 04:10:01

标签: javascript angular

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

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 个答案:

答案 0 :(得分:2)

这是因为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的形式附加到tab标签中(4默认为空格),默认将startindex设置为5
  2. 第二行-索引从1开始-按照编写的HTML代码段添加新的行字符。
  3. 第三行-正常行为。
  4. 第四行-索引的末尾值比实际索引大1-在末尾附加一个newline字符。

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>

仅在选择单个元素中的内容时,上述片段才可以完美工作。如果选择了多个元素,则需要修改实现。

答案 1 :(得分:0)

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

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:您的范围和文档将成为文档

此函数将为您返回带偏移的新范围