Firefox三击选择返回错误的开始和结束偏移

时间:2014-01-20 08:16:32

标签: javascript html firefox selection

我有这段代码应该返回用户选择的开始和结束偏移:

<!DOCTYPE html>
 <html>
  <head>
   <script type="text/javascript">
    function getSelRange() {
      var selObj = window.getSelection();
      var range  = selObj.getRangeAt(0);
      alert(range.startOffset+"-"+range.endOffset);
    }

   </script>
  </head>
  <body>
    <button onclick="getSelRange()">Get the selected text!</button>
    <p>Select some text!</p>
  </body>
</html>

当我通过拖动从p中选择一些文字时,它会正确提醒数字。但是,当我通过三次点击选择p中的整个文字时,它会提醒 0-1 。看起来只在Firefox中,三次点击不能正确返回选择范围。

如何在三次点击时获得正确的起点和终点?

2 个答案:

答案 0 :(得分:2)

Firefox正在返回正确的范围。问题是您假设范围必须具有相对于文本节点的起始和结束边界是不正确的。

正在发生的事情是Firefox将范围报告为在<p>元素的第0个子节点之前开始并在<p>元素的第一个子节点之后结束。这完全有效。

您可以执行以下操作来调整此范围,使其边界位于<p>元素内的文本节点内:

演示:http://jsfiddle.net/DbmjH/2/

代码:

function adjustRange(range) {
    range = range.cloneRange();
    if (range.startContainer.nodeType != 3) {
        var nodeAfterStart = range.startContainer.childNodes[range.startOffset];
        if (nodeAfterStart && nodeAfterStart.nodeType == 3) {
            range.setStart(nodeAfterStart, 0);
        }
    }
    if (range.endContainer.nodeType != 3 && range.endOffset >= 1) {
        var nodeBeforeEnd = range.endContainer.childNodes[range.endOffset - 1];
        if (nodeBeforeEnd && nodeBeforeEnd.nodeType == 3) {
            range.setEnd(nodeBeforeEnd, nodeBeforeEnd.data.length);
        }
    }
    return range;
}

答案 1 :(得分:1)

Check this fiddle更新

我的方式是,当段落包含多行时,它会在三次点击时起作用。

<script>
    function getSelRange() {
        var selObj = window.getSelection();
        var range = selObj.getRangeAt(0);
        var r = document.getElementById('txt').innerHTML.split('<br>');

        if (r[(range.endOffset-1)/2] == selObj) {
            alert(0+"-"+r[(range.endOffset-1)/2].length);
        } else if (range.startOffset >= range.endOffset) {
            alert(range.startOffset + "-" + r[(range.endOffset-1)/2].length);
        } else {
            alert(range.startOffset + "-" + range.endOffset);
        }  
    }
</script>

New Added Fiddle

<script>
function getSelRange() {
    var selObj = window.getSelection();
    var range  = selObj.getRangeAt(0);
    var r=document.getElementById('txt').innerHTML.split('<br>');
    var selLines = selObj.toString().split('\n');

    var Str = document.getElementById('txt').innerHTML;
    Str=Str.replace(/<br>/g,"xzznlzzx");
    var pr=selObj.toString().replace(/\r?\n/g,"xzznlzzx");
    var rStr=Str.substring(0,Str.indexOf(pr));

    var rSplit=rStr.split('xzznlzzx');
    var prSplit=pr.split('xzznlzzx');

    var countStart=0;
    var countEnd=0;
    var i=0;
    for(;i<(rSplit.length-1);i++)
    {
        countStart=countStart+r[i].length;
    }
    for(j=0;j<(prSplit.length-1);i++,j++)
    {
        countEnd=countEnd+r[i].length;
    }

    countEnd=countEnd+countStart;
    if(r[(range.endOffset-1)/2]==selObj)
    {
    alert((0+countStart)+"-"+(r[(range.endOffset-1)/2].length+countEnd));
    }
    else{
        if(r[i].length<selObj.toString().length)
        {
        var indx = selObj.toString().indexOf(r[i]);
        }
        else{
        var indx = r[i].indexOf(selObj.toString());
        var vals=selObj.toString().length;
        var res = r[i].substring(indx+vals,indx+vals+1);
        if(res==""){indx=1}
        else{indx=-1}
        }
        if(indx!=-1)
        {
        alert((range.startOffset+countStart)+"-"+(r[i].length+countEnd));
        }
        else{
        alert((range.startOffset+countStart)+"-"+(range.endOffset+countEnd));
        }
    } 
}
</script>

注意:要使上述小提琴起作用,<p>标记内的字符串必须在一行中,否则会在单词之间添加额外的空格。 < / em>的