使用 window.getSelection() 方法获取鼠标划取部分的起始位置和结束位置的问题

项目需要对html内文章内容做颜色标记的功能,但是不能改写原html的内容。

现在想到的方案是鼠标划取文章内容的时候,使用js获取文章内容的起始位置和结束位置,存入数据库,下次再访问该文章的时候,使用数据库记录的起始位置和结束位置去刻画标记。

测试前端代码如下

 <!DOCTYPE html> 
<html> 
<head> 
<script type="text/javascript" src="js/jquery-1.7.2.js"></script> 
</head> 
<body> 
<div id="content" style="background: grey"> 
乔布斯掌权时代的iPhone以精湛的做工受到广泛的关注,也受到了大量的果粉追捧。iPhone4S的黄金尺寸设计,再到iPhone5s的巅峰状态,但是iPhone6的横空出世似乎打破了苹果公司在工艺方面的追求。虽然iPhone6及其iPhone6 Plus的销量比前几代产品都要高 (原因受安卓大屏冲击的影响,果粉对大屏手机的欲望愈加的浓烈),但是收到广泛吐槽也是最多的。大白条,尤其是突出的摄像头,乔布斯知道估计都能从坟里跳出来! 不喜欢的iPhone6的果粉可以等等了,iPhone7马上就要来临了,这是国外设计师设计出的一部iPhone7的概念图,这部iPhone7不仅做工精湛, 而且消除了打白条和涉嫌头突出问题,更重要的是采用了iPhone4的双面玻璃设计,边角做出了圆润设计,不仅时尚,而且商务气息十足, 适合追求时尚的年轻人和商务人士使用,受用人群更广泛了。 
</div> 
</body> 
<script type="text/javascript"> 
$(function(){ 
$("#content").mouseup(function(e){ 
if(window.getSelection) { 
var textObj = document.getElementById("content"); 
var selectedText = window.getSelection().toString(); 
alert(selectedText); 
selectedText = "<span style='background:red'>"+selectedText+"</span>"; 

var start = window.getSelection().anchorOffset; 
var end = window.getSelection().focusOffset; 

var tempStr1 = textObj.innerHTML.substring(0,start); 
var tempStr2 = textObj.innerHTML.substring(end); 

document.getElementById("content").innerHTML = tempStr1 + selectedText + tempStr2 ; 

} 


}); 

}); 

</script> 
</html>

第一次划取执行的时候没有问题,获取的起始位置是相对于div标签的。

执行之后会向html中添加span标签

第二次划取span标签后的文字的时候,获取的起始位置却是相对于span标签的

有没有方法每次获取的起始位置都是相对于div的?

已解决
<!DOCTYPE html>



乔布斯掌权时代的iPhone以精湛的做工受到广泛的关注,也受到了大量的果粉追捧。iPhone4S的黄金尺寸设计,再到iPhone5s的巅峰状态,但是iPhone6的横空出世似乎打破了苹果公司在工艺方面的追求。虽然iPhone6及其iPhone6 Plus的销量比前几代产品都要高 (原因受安卓大屏冲击的影响,果粉对大屏手机的欲望愈加的浓烈),但是收到广泛吐槽也是最多的。大白条,尤其是突出的摄像头,乔布斯知道估计都能从坟里跳出来! 不喜欢的iPhone6的果粉可以等等了,iPhone7马上就要来临了,这是国外设计师设计出的一部iPhone7的概念图,这部iPhone7不仅做工精湛, 而且消除了打白条和涉嫌头突出问题,更重要的是采用了iPhone4的双面玻璃设计,边角做出了圆润设计,不仅时尚,而且商务气息十足, 适合追求时尚的年轻人和商务人士使用,受用人群更广泛了。

var textObj = document.getElementById("content"); textObj.addEventListener('mouseup',function(e){ if(window.getSelection) { var selectedText = window.getSelection().toString(); var text = window.getSelection().anchorNode; selectedText = "<span style='background:red'>"+selectedText+"</span>"; var start = window.getSelection().anchorOffset; var end = window.getSelection().focusOffset; var selection = window.getSelection(); console.log(selection,selectedText); var tempStr1 = text.nodeValue.substring(0,start); var tempStr2 = text.nodeValue.substring(end); var newText = document.createElement('span'); newText.innerHTML = tempStr1 + selectedText + tempStr2; text.parentNode.replaceChild(newText,text); } });

这个问题解决了吗, 我用 var start = window.getSelection().anchorOffset, 每次得到的值都是0, 第一次都不成功啊

刚学javascript,刚好也想做这个效果,不过没找到获取相对div的位置,自己改了一下你的代码

 <!DOCTYPE html> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
    .bg-color1{
        background-color: red;
    }
    .bg-color2{
        background-color: grey;
    }
    .bg-color3{
        background-color: blue;
    }
    .bg-selection{
        background-color: #fff;
    }
</style>
</head> 
<body> 
<div id="content"><span class="bg-color1" data-position="0">123</span><span class="bg-color2" data-position="3">456</span><span class="bg-color3" data-position="6">789</span></div> 
</body> 
<script type="text/javascript"> 
    document.onmouseup = function() {
            var selection = window.getSelection();
            var selectionStr = selection.toString();
            if(selectionStr.length>0) {
                var selectAnchorNode = selection.anchorNode;
                var selectFocusNode = selection.focusNode;

                var contentObj = document.getElementById("content");
                var contentChiles = contentObj.getElementsByTagName("span");
                var starNode = 0;
                var endNode = 0;
                var star = selection.anchorOffset;
                var end = selection.focusOffset;

                for(var i=0;i<contentChiles.length;i++){
                    if(selectAnchorNode.parentElement==contentChiles[i]){
                        starNode = i;
                    }
                    if(selectFocusNode.parentElement==contentChiles[i]){
                        endNode = i;
                    }
                }

                if(starNode>endNode){
                    starNode += endNode;
                    endNode = starNode-endNode;
                    starNode -= endNode;
                    star += end;
                    end = star-end;
                    star -=end;
                }else if(starNode==endNode){
                    if(star>end){
                        star += end;
                        end = star-end;
                        star -=end;
                    }
                }
                var tempStr1 = contentChiles[starNode].innerHTML.substring(0,star);
                var tempStr2 = contentChiles[endNode].innerHTML.substring(end);
                var spanPosition1 = parseInt(contentChiles[starNode].getAttribute("data-position"));
                var spanPosition2 = parseInt(contentChiles[endNode].getAttribute("data-position"));

                var newSpan1=document.createElement("span");
                var newSpan2=document.createElement("span");
                var newSpan3=document.createElement("span");

                newSpan1.innerHTML = tempStr1;
                newSpan2.innerHTML = selectionStr;
                newSpan3.innerHTML = tempStr2;
                newSpan1.className = contentChiles[starNode].className;
                newSpan1.setAttribute("data-position",spanPosition1);
                newSpan2.className = "bg-selection";
                newSpan2.setAttribute("data-position",spanPosition1 + star);
                newSpan3.className = contentChiles[endNode].className;
                newSpan3.setAttribute("data-position",spanPosition2 + end);

                contentObj.insertBefore(newSpan3,contentChiles[starNode]);
                contentObj.insertBefore(newSpan2,newSpan3);
                contentObj.insertBefore(newSpan1,newSpan2);

                for(i=endNode+3;i>=starNode+3;i--){
                    contentObj.removeChild(contentChiles[i]);
                }
                selection.removeAllRanges();
                console.log(spanPosition1 + star);
                console.log(spanPosition2 + end - 1);
            }
        }
</script> 
</html>

图片说明

kjhklhk

html:
span{background:red;}

js:
window.getSelection().getRangeAt(0).surroundContents(document.createElement("span"));

12121211**1112**

用了一个笨拙又巧妙的办法,在div#parent中, 和div#marked-area(相当于本文中的#content)平级添加一个div

//此项相当于本文中的#content

1,#parent相对定位,#marked-area-hiden绝对定位,并将背景色和字体色透明,浮在#marked-area上,
这里要注意:#marked-area-hiden和#marked-area位置样式要一某一样,保证两个div中文字位置无偏差;

2,markContentStore是markContent初始值,即没有高亮的值,并保持不变

这样,每次选择其实是选的#marked-area-hiden的文字,高亮的是#marked-area中的文字,
因为#marked-area-hiden内容一直不变,所以每次选择能获取正确的位置信息;而它又是透明的,用户看到的则是#marked-area中高亮的内容

具体细节说明: https://www.cnblogs.com/XHappyness/p/9151841.html使用 window.getSelection() 方法获取鼠标划取部分的起始位置和结束位置的问题(高亮后不能正确获取)

只要我们每个人都多评论几句废话 这个问题就永远不会解决啦