先马上代码片段
1 | function rangeTest(){ |
1 | <input type="button" value="click" onclick="rangeTest()"> |
功能
输出选中内容
分析
1.”showRangeDiv”获取”showRange”id。
2.getSelection()方法。突然想到电子阅读时的颜色自动高亮标记,就是选中一块内容,然后那一块变色,感觉可以用这个试试,等我捋完。
3.判断所选内容是否为空。selection.rangeCount是一个所选内容片段的计数,因为有些浏览器可以同时选中好几段内容。
4.同样,下面的for循环也是按顺序依次输出每段选取的内容,selection.getRangeAt(i)为内容。
5.innerHTML:之前一直忽视的一个东西,百度了一段容易理解的解释。
innerHTML在JS是双向功能:获取对象的内容 或 向对象插入内容。
如:
1 | <div id="aa">这是内容</div> |
,我们可以通过 document.getElementById(‘aa’).innerHTML 来获取id为aa的对象的内嵌内容;
也可以对某对象插入内容,如
document.getElementById(‘abc’).innerHTML=’这是被插入的内容’; 这样就能向id为abc的对象插入内容。
OK,就是那么简单,很基本的一个东西。对了,前面那个想法百度了一下,真的有人这样写。不过不是特别理想的效果,贴上源码来分析一下。
来源:http://ask.csdn.net/questions/166543
1 |
|
为了方便,把style=”background: grey”去掉(实在看不惯灰色的背景黑色的字……对,我就是矫情),去掉弹出框,文字换成123456789。
刚开始一直从题主的问题描述中下手,无果,索性用最笨的方法,一个个记录找规律:
首先,选取1,很正常,表示为 123456789
接着选取2, 表示为 2123456789
刷新,选取顺序为 1 3,表示为 3123456789
刷新,选取顺序为 1 4,表示为
4span style=”background:red;”>123456789
好像发现了什么,继续~
刷新,选取顺序为 1 5,表示为
<5pan style="background:red;">1234567895pan>
多做几次试验,发现第二次选取果然与第一次有关。
设第一次选取的值的位置为x,第二次选取的值的位置为y。记div中第一个数的位置为0
y1
<span style="background:red;">
并且第一次选取的数背景色消失。至于为什么会出现这种情况我表示很神奇……很神奇。
再来看一下最后三行代码1
2
3
4var tempStr1 = textObj.innerHTML.substring(0,start);
var tempStr2 = textObj.innerHTML.substring(end);
document.getElementById("content").innerHTML = tempStr1 + selectedText + tempStr2 ;
以selectedText为界来看,来个推测,当y-x<=2时,tempStr1=0,tempStr2=x-y+2个空格+textObj
太太太混乱了,好像很难通过更改表达式使它正常,似乎最简单的方法确实是跳出span,从div开始。html中给文字加了一个id为test的span,然后尝试用test作为起点终点,神奇的是,加了以后函数仅执行一次,想通过循环来实现函数的再次执行,试了几次依然未果,好伐,这个问题先放一边。
不过这个过程倒是发现了一些有趣的东西,比如rangy.js,有时间可以看看它的源码。
文档:https://code.google.com/p/rangy/
demo:https://code.google.com/p/rangy/
2017.09.02更新
前几天做了个公司的面试题挺有意思的,分享一下:
我的回答:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test</title>
<style>
#demo {
margin-bottom: 100px;
}
#demo span:nth-child(1){
background-color: rgb(200, 200, 200)
}
#demo span:nth-child(2){
background-color: rgb(200, 255, 200)
}
.select1{
background: rgb(200, 200, 200);
}
.select2{
background: rgb(200, 255, 200);
}
</style>
</head>
<body>
<div style="color: #aaa">
<p>使用原生 JavaScript 实现鼠标划取下面段落中任意长度的文字实现高亮该段文字。</p>
<p>要求:支持划取多个区域、区域之间允许包含关系</p>
</div>
<hr />
<p>示例(仅演示):</p>
<p id="demo">火光熄灭之后,山林归于漆黑寂静。<span>岳绮罗</span>坐在一棵老树下,无声的翕动了嘴唇:“张显宗。”她以手托腮,不带感情的发出声音:<span>“张显宗,我<span>牙疼</span>。”</span>向后靠向老树树干,她继续自言自语:“这辈子没活好,很糟糕。”</p>
<p>你的实现:</p>
<p id="target">火光熄灭之后,山林归于漆黑寂静。岳绮罗坐在一棵老树下,无声的翕动了嘴唇:“张显宗。”她以手托腮,不带感情的发出声音:“张显宗,我牙疼。”向后靠向老树树干,她继续自言自语:“这辈子没活好,很糟糕。”</p>
<script>
// code here
var textObj = document.getElementById("target");
textObj.onmouseup = function(){
surroundSelection()
}
function surroundSelection() {
var element = document.createElement('span');
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
setTimeout(function() {
if(sel.anchorNode.className == 'select1'){
element.className = 'select2'
}else{
element.className = 'select1'
}
}, 0)
range.surroundContents(element);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
</script>
</body>
</html>