1.获取用户网页选中内容

<p>4月13日消息,据台湾媒体报道,32岁的孙燕姿(Sng Ee Tze)和后天将满34岁的荷兰籍印度尼西亚男友纳迪姆(Nadim Van Der Ros)交往5年,曾说过"有空就结婚"的她,果然趁着宣传期尾声,于3月31日在新加坡登记注册了!昨消息传开,她未否认,仅说会选择适当时间公布喜讯,所属"美妙音乐"则表示她个性低调,婚礼只会邀请双方亲友,也不会透露细节,但据新加坡可靠消息指出,婚宴订在5月初。</p>
<button id="button">选中一些文字,然后点击本按钮</button>
JS代码:
<script> //获取网页中选中内容
var oBtn = document.getElementById("button"); oBtn.onclick = function () {
var userSelection, text;
if (window.getSelection) { //现代浏览器
userSelection = window.getSelection();
} else if (document.selection) { //IE浏览器 考虑到Opera,应该放在后面
userSelection = document.selection.createRange(); } if (!(text = userSelection.text)) {
text = userSelection;
}
alert(text);
};
</script>

一:Range对象的概念

Range对象代表页面上一段连续的区域,通过Range对象可以获取或者修改页面上任何区域的内容。也可以通过Range的方法进行复制和移动页面任何区域的元素。
在Js的document文档中有一个方法用来创建一个Range对象,代码如下:

var  range = document.createRange();

在html5中,每一个浏览器窗口都会有一个selection对象,代表用户鼠标在页面中所选取的区域,(注意:经过测试IE9以下的浏览器不支持Selection对象), 可以通过如下语句创建selection对象;

var  selection = document.getSelection();
或者
var selection = window.getSelection();

每一个selection对象都有一个或者多个Range对象,每一个range对象代表用户鼠标所选取范围内的一段连续区域,在firefox中,可以通过ctrl键可以选取多个连续的区域,因此在firefox中一个selection对象有多个range对象,在其他浏览器中,用户只能选取一段连续的区域,因此只有一个range对象。
可以通过selection对象的getRangeAt方法来获取selection对象的某个Range对象,如下:
getRangeAt方法有一个参数index,代表该Range对象的序列号;我们可以通过Selection对象的rangeCount参数的值判断用户是否选取了内容;
1.当用户没有按下鼠标时候,该参数的值为0.
2.当用户按下鼠标的时候,该参数值为1.
3.当用户使用鼠标同时按住ctrl键时选取了一个或者多个区域时候,该参数值代表用户选取区域的数量。
4.当用户取消区域的选取时,该属性值为1,代表页面上存在一个空的Range对象;
测试代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<script>
function rangeTest() {
var html,
showRangeDiv = document.getElementById("showRange"),
selection = document.getSelection();
if(selection.rangeCount > 0) {
html = "你选取了" + selection.rangeCount + "段内容<br/>";
for(var i = 0; i < selection.rangeCount; i++) {
var range = selection.getRangeAt(i);
html += "第" + (i + 1) + "段内容为:" + range + "<br/>";
}
showRangeDiv.innerHTML = html;
}
}
</script>
<h3>selection对象与range对象的使用实例</h3>
<input type="button" value="点击我" onclick="rangeTest()"/>
<div id="showRange"></div>
</body>
</html>

效果:

 
range_selection.png

二:Range对象的属性和方法

(1)属性

startContainer
包含“起点”的节点。“包含”的意思是起点所属的节点。
endContainer
包含“结束点”的节点
startOffset
“起点”在startContainer中的偏移量。
如果startContainer是文本节点、注释节点或CDATA节点,则返回“起点”在startContainer中字符偏移量。
如果startContainer是元素节点,则返回“起点”在startContainer.childNodes中的次序。

<p id="p1"><span>span</span><b id="b1">Hello</b> World</p>
<script type="text/javascript">
var oP1 = document.getElementById('p1') ;
var oB1 = document.getElementById('b1');
var oRange = document.createRange();
oRange.setStart(oB1.firstChild, 2); // 设置range的“起点” oRange.setEnd(oP1.lastChild, 3); // 设置range的“结束点” alert(oRange.startOffset); // 2,可看到“起点”在<b id="b1">Hello</b>应是第三个字符。
alert(oRange.startContainer); // 元素oB1.firstChild,文本节点</script>

collapsed:
起点和结束点在一起时为true;Range对象为空(刚createRange()时)也为true。
commonAncestorContainer
第一个包含Range的节点,同时包含起点和结束点。

(2)定位(设置“起点”和“结束点”)的一些方法

setStart(node, offset)和setEnd(node, offset)
setStart:设置起点的位置,node是对startContainer的引用,偏移则是startOffset;
setEnd:设置结束点的位置,node是对endContainer的引用,偏移则是startOffset;
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>range3</title>
<script>
function deleteChar() {
var div = document.getElementById("myDiv");
var textNode = div.firstChild;
var rangeObj = document.createRange();
rangeObj.setStart(textNode,1);
rangeObj.setEnd(textNode,4);
rangeObj.deleteContents();
}
</script>
</head>
<body>
<div id="myDiv" style="color:red">这段文字是用来删除的</div>
<button onclick="deleteChar()">删除文字</button>
</body>
</html>

setStartBefore(referenceNode)、setStartAfter(referenceNode)
setEndBefore(referenceNode)、setEndAfter(referenceNode)

setStartBefore:将“起点”设置到referenceNode前
setStartAfter:将“起点”设置到referenceNode后
setEndBefore:将“结束点”设置到referenceNode前
setEndAfter:将“结束点”设置到referenceNode后
注意:使用这四个方法设置的“起点”或“结束点”的父节点与referenceNode的父节点是同一个元素。
代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="application/javascript">
function delrow(){
var table=document.getElementById("mytable");
if(table.rows.length>0){
var row=table.rows[0];
var rangeObj=document.createRange();
rangeObj.setStartBefore(row);
rangeObj.setEndAfter(row);
rangeObj.deleteContents();
}
}
</script>
</head>
<body>
<table id="mytable" border="1">
<tr>
<td>内容1</td>
<td>内容2</td>
</tr>
<tr>
<td>内容3</td>
<td>内容4</td>
</tr>
</table>
<button onclick="delrow()">删除第一行</button>
</body>
</html>

selectNode(referenceNode)和selectNodeContents(referenceNode)
selectNode:设置Range的范围,包括referenceNode和它的所有后代(子孙)节点。
selectNodeContents:设置Range的范围,包括它的所有后代节点。
二者的区别:

 
range_selection.png

(3)修改范围的方法

cloneRange()
cloneRange()方法将返回一个当前Range的副本,它也是Range对象。
注意它和cloneContents()的区别在于返回值不同,一个是HTML片段,一个是Range对象 。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<p id="p">这里是随便书写的内容</p>
<button onclick="cloneRange()">克隆</button>
</body>
<script>
function cloneRange() {
var rangeObj = document.createRange();
rangeObj.selectNodeContents(document.getElementById("p"));
var rangeClone = rangeObj.cloneRange();
alert(rangeClone.toString());
}
</script>
</html>

cloneContents()
可以克隆选中Range的fragment并返回改fragment。这个方法类似extractContents(),但不是删除,而是克隆。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<p id="p">这里是随便书写的内容</p>
<button onclick="cloneContents()">克隆</button>
</body>
<script>
function cloneContents() {
var rangeObj = document.createRange();
rangeObj.selectNodeContents(document.getElementById("p"));
var rangeClone = rangeObj.cloneContents();
alert(rangeClone.toString());
}
</script>
</html>

deleteContents()
从Dom中删除Range选中的fragment。注意该函数没有返回值(实际上为undefined)。
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<p id="p">这里是随便书写的内容</p>
<button onclick="delRange()">删除</button>
</body>
<script>
function delRange() {
var rangeObj = document.createRange();
rangeObj.selectNodeContents(document.getElementById("p"));
var rangeClone = rangeObj.deleteContents();
}
</script>
</html>

extractContents()
将选中的Range从DOM树中移到一个fragment中,并返回此fragment。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<div id="srcDiv" style="background-color:aquamarine;width:300px;height:50px;">你好吗?</div>
<div id="distDiv" style="background-color:bisque;width:300px;height:50px"></div>
<button onclick="moveContent()">移动元素</button>
</body>
<script>
function moveContent() {
var srcDiv = document.getElementById("srcDiv");
var distDiv = document.getElementById("distDiv");
var rangeObj = document.createRange();
rangeObj.selectNodeContents(srcDiv);
var docFrangMent = rangeObj.extractContents();
distDiv.appendChild(docFrangMent);
}
</script>
</html>

insertNode
insertNode方法可以插入一个节点到Range中,注意会插入到Range的“起点”。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<p id="p1"><b>Hello</b> World</p>
</body>
<script>
var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
var oSpan = document.createElement("span");
oSpan.appendChild(document.createTextNode("Inserted text"));
oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
oRange.insertNode(oSpan);
</script>
</html>

compareBoundaryPoints()

var compare = comparerange.compareBoundaryPoints(how, sourceRange);

compare:返回1, 0, -1.(0为相等,1为时,comparerange在sourceRange之后,-1为comparerange在sourceRange之前)。
how:比较哪些边界点,为常数。
Range.START_TO_START - 比较两个 Range 节点的开始点
Range.END_TO_END - 比较两个 Range 节点的结束点
Range.START_TO_END - 用 sourceRange 的开始点与当前范围的结束点比较
Range.END_TO_START - 用 sourceRange 的结束点与当前范围的开始点比较
sourceRange:个Range对象的边界。
detach()
虽然GC(垃圾收集器)会将其收集,但用detach()释放range对象是一个好习惯。语法为:oRange.detach();
toString()
返回该范围表示的文档区域的纯文本内容,不包含任何标签;

作者:便U_Life
链接:https://www.jianshu.com/p/ad2f818cc3b0
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

参考文档:

https://www.jianshu.com/p/ad2f818cc3b0

http://www.zhangxinxu.com/wordpress/2011/04/js-range-html%E6%96%87%E6%A1%A3%E6%96%87%E5%AD%97%E5%86%85%E5%AE%B9%E9%80%89%E4%B8%AD%E3%80%81%E5%BA%93%E5%8F%8A%E5%BA%94%E7%94%A8%E4%BB%8B%E7%BB%8D/

JS Range使用整理的更多相关文章

  1. js数组学习整理

    原文地址:js数组学习整理 常用的js数组操作方法及原理 1.声明数组的方式 var colors = new Array();//空的数组 var colors = new Array(3); // ...

  2. JS正则表达式大全(整理详细且实用)

    JS正则表达式大全(整理详细且实用).需要的朋友可以过来参考下,希望对大家有所帮助!! 正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释, ...

  3. Js Date泣血整理

    原文:Js Date泣血整理 JS Date 对象用于处理日期和时间. 创建 Date 对象的语法: var myDate=new Date() Date 对象会自动把当前日期和时间保存为其初始值. ...

  4. vue.js面试题整理

    Vue.js面试题整理 一.什么是MVVM? MVVM是Model-View-ViewModel的缩写.MVVM是一种设计思想.Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务 ...

  5. SVG.js 元素操作整理(二)-Transform

    一.transform()获取或设置矩阵变换 var draw = SVG('svg1').size(300, 300); //Transforming SVG元素矩阵变换 var rect = dr ...

  6. SVG.js 元素操作整理(一)

    一.属性操作Attributes var draw = SVG('svg1').size(300, 300); //attr() 属性操作 //设置属性的值 var rect = draw.rect( ...

  7. 【前端芝士树】Vue.js面试题整理 / 知识点梳理

    [前端芝士树] Vue.js 面试题整理 MVVM是什么? MVVM 是 Model-View-ViewModel 的缩写. Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑. ...

  8. 常用的 JS 排序算法整理

    关于排序算法的问题可以在网上搜到一大堆,但是纯 JS 版比较零散,之前面试的时候特意整理了一遍,附带排序效率比较. //1.冒泡排序 var bubbleSort = function(arr) { ...

  9. SVG.js 文本绘制整理

    1.SVG.Text var draw = SVG('svg1').size(300, 300); //画文字内容展示 //var text = draw.text('中文内容测试\n换行处理'); ...

随机推荐

  1. 造轮子和用轮子:快速入门JavaScript模块化

    造轮子和用轮子:快速入门JavaScript模块化 前言 都说“不重复造轮子”,就像iPhone——它除了打电话还可以播放音乐——但是工程师不用从零开始做一个音乐播放功能,也许只要在iPhone的系统 ...

  2. 【linux】centos6.9安装gearman

    1.确认yum源没问题,如果有问题,参照这里更换 2. yum install -y boost-devel gperf libevent-devel libuuid-devel yum instal ...

  3. 性能测试四:jmeter进阶之逻辑控制器

    常用的逻辑控制器 1,循环控制器:可以设置该控制器内的sampler执行的次数,循环次数与线程的循环次数各自独立 2,if控制器:根据判断条件决定是否执行该控制器内的请求,如果是字符串比较条件,参数和 ...

  4. 步步为营-69-Razor基础

    作用:进一步将HTML代码和C#代码进行解耦 1.1 引用程序集(RazorEngine.dll,System.Web.Razor.dll) 1.1.1 可以从http://razorengine.c ...

  5. git merge简介

    git merge的基本用法为把一个分支或或某个commit的修改合并到现在的分支上.我们可以运行git merge -h和git merge --help查看其命令,后者会直接转到一个网页(git的 ...

  6. DFS基础题

    hdu 1241 油田  裸DFS 题意:@代表油田 8个方向上还有@就相连 相当于求图中连通子图的个数Sample Input1 1 // n m*3 5*@*@***@***@*@*1 8@@** ...

  7. jquery 中remove()与detach()的区别

    remove()与detach()方法都是从dom中删除所有的元素 两者的共同之处在于都不会把匹配的元素从jQuery对象中删除. 不同之处在于用remove()删除的元素,除了元素被保留,其他的在这 ...

  8. jquery中方法扩展 ($.fn & $.extend) 学习笔记

    A.$.fn 1.$.fn.method() 函数为jQuery对象扩展一个属性和方法(主要用于扩展方法) :method 为自定义方法名 ($.fn 等效 $.prototype) $.fn.bor ...

  9. python tkinter-窗体

    1.导入自带的包名 import tkinter 2.创建一个窗体对象 form=Tkinter.Tk() 3.显示窗体(这句应该是所有的设置部署完最后执行的一句代码) form.mainloop() ...

  10. python str,list,tuple转换

      1. str转listlist = list(str) 2. list转strstr= ''.join(list) 3. tuple list相互转换tuple=tuple(list)list=l ...