项目需要对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>
这个问题解决了吗, 我用 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>
html:
span{background:red;}
js:
window.getSelection().getRangeAt(0).surroundContents(document.createElement("span"));
12121211**1112**
用了一个笨拙又巧妙的办法,在div#parent中, 和div#marked-area(相当于本文中的#content)平级添加一个div
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中高亮的内容
只要我们每个人都多评论几句废话 这个问题就永远不会解决啦