通过DOM范围可以选择文档中的某个区域,而不需考虑节点的界限,例如文本高亮的处理就可以使用范围来实现。

1、Range的创建

使用document的createRange来创建一个范围,该方法返回一个Range实例,该实例有很多属性和方法,如下所示:

startContainer:包含范围起点的节点

startOffset:范围起点在startContainer中的偏移量,既节点索引

endContainer:包含范围终点的节点

endOffset:范围终点在endContainer的偏移量,节点索引+1

检测浏览器是否支持范围

document.implementation.hasFeature('Range','2.0')  OR
typeof document.createRange === 'function'

创建范围

var range = document.createRange();
//由于IE8及以下浏览器不支持DOM Range,但是支持文本范围(document.body.createTextRange)
var range = document.body.createTextRange();

2、Range的实例方法

假设有一个HTML文档如下所示

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="outer" id="outer">
<div class="inner" id="inner1">hello world!</div>
<div class="inner" id="inner2"><span>你好吗</span></div>
</div>
</body>
</html>

选择文档的一部分,可以使用selectNode或者selectNodeContents方法,如下所示

var range = document.createRange();
range.selectNode(inner1);
console.log(range.startOffset);//1 因为空格被当作一个文本节点
---------------------------------------------------
var range = document.createRange();
range.selectNodeContents(outer);
console.log(range.endOffset);//5
//IE8以下
var range = document.body.createTextRange();
range.findText("hello");
console.log(range.text);//hello range.moveToElementText(inner1);
console.log(range.htmlText);

也可以使用setStartBefore、setStartAfter、setEndBefore、setEndAfter等方法来选择文档范围

var range = document.createRange();
range.setStartBefore(inner1);
range.setEndBefore(inner2);
console.log(range.endOffset);//3

还可以使用setStart和setEnd来选择,这两个函数均需要两个参数,一个参照节点,一个偏移量,对于setStart来说,参照节点便是startContainer,而setEnd的参照节点是endContainer

var range = document.createRange();
range.setStart(inner1,0);
range.setEnd(inner1,inner1.childNodes.length);
console.log(range.endOffset);//1
//IE8以下
range.moveStart("word", 2); //起点移动2 个单词
range.moveEnd("character", 1); //终点移动1 个字符
-----------------------------------------
"character":逐个字符地移动。
"word":逐个单词(一系列非空格字符)地移动。
"sentence":逐个句子(一系列以句号、问号或叹号结尾的字符)地移动。
"textedit":移动到当前范围选区的开始或结束位置。

操作选区中内容

1、从文档中删除选区的内容deleteContents和extractContents,他们的区别就是后者会返回删除的文档片段,如下所示

var range = document.createRange();
range.setStart(inner1.firstChild,0);
range.setEnd(inner1.firstChild,5);
//range.deleteContents();
var fragment = range.extractContents();
box.appendChild(fragment);

2、复制选区内容cloneContents,复制出来的只是范围中节点的副本,不是真实的节点

var range = document.createRange();
range.setStart(outer,0);
range.setEnd(outer,outer.childNodes.length);
var fragment = range.cloneContents();
box.appendChild(fragment);

3、向范围中插入内容insertNode或者surroundContents

var range = document.createRange();
range.selectNodeContents(outer);
var span = document.createElement('span');
span.innerText = "我知道了";
range.insertNode(span);//会在范围的开始处插入指定节点
------------------------------------------------------------------
var range = document.createRange();
range.setStart(inner1.firstChild,0);
range.setEnd(inner1.firstChild,5);
var span = document.createElement('span');
span.className = "red";
range.surroundContents(span);
//ie8以下
var range = document.body.createTextRange();
range.findText("Hello");
range.text = "Howdy";
-------------------------------------
range.pasteHTML("<em>Howdy</em>");//类似与range.surroundContents

4、复制Range和清理Range

复制range,使用cloneRange方法,该方法复制出来的是指定范围的副本;使用detach方法把范围从文档中分离,然后解除范围的引用

var range = document.createRange();
range.setStart(inner1.firstChild,0);
range.setEnd(inner1.firstChild,5);
var rangeBak = range.cloneRange();
var fragment = rangeBak.extractContents();
box.appendChild(fragment);
range.detach();
range = null;

Notes: DOM Range的更多相关文章

  1. XML DOM - Range 对象

    Range对象 Range对象表示文档的连续范围区域,如用户在浏览器窗口中用鼠标拖动选中的区域.   dom标准Range对象 在IE中使用TextRange对象 range对象常用的建立方法在开发中 ...

  2. JS 之DOM range对象

    DOM范围 DOM中的range对象是DOM2中新定义的接口.通过这个对象可以选择文档中的某个区域,而不必考虑节点的界限. 创建范围 document.createRange()创建一个范围,这个范围 ...

  3. Notes:DOM的事件模拟

    首先使用document对象的createEvent方法创建一个事件对象,然后初始化该事件对象,接着使用支持事件DOM节点的dispatchEvent方法触发事件. DOM2级事件和DOM3级事件有些 ...

  4. 十几张表的join(千万级/百万级表) 7hours-->5mins

    ================START============================== 来了一个mail说是job跑得很慢,调查下原因 先来看下sql: SELECT h.order_ ...

  5. 百度UEditor基本使用

    1 首先奉上链接其http://ueditor.baidu.com/website/index.html 更多更详细内容在其官方api上,本文只是一个归类总结性文章. 2 下载链接http://ued ...

  6. 可编辑的DIV -编辑器

    找了好多,没几个好用的,都或多或少有问题 目前这个最好用..  不过有一个奇葩的问题,就是要放在"<a></a>"标签里面, js或者jQuery获取  $ ...

  7. Ckeditor 的加载顺序

    我们的只用在文件里面引用一个CKEditor的js文件--CKEditor目录下的ckeditor.js文件, 该文件会完成后续的所有的CKEidtor依赖的js文件的加载. 所依赖的js文件加载顺序 ...

  8. API返回错误信息的最佳实践

    使用HTTP Status区分不同消息返回 最基础的三个状态200 OK, 400 Client Error, 500 Server Error 这些应该是够的, 如果客户端可以处理更细的划分, 可以 ...

  9. UEditor API 文档

    来源:http://www.e4dai.com/ueditor-api/#ue.editor http://www.e4dai.com/ueditor-api/ UE.Editor 依赖 editor ...

随机推荐

  1. C# SQL 面试题自我总结

    1,asp.net单点登录机制 2,多线程同步机制 3,写一个冒泡排序算法 4,写一个递归算法 5,字符串反转 字符串分隔后调用reverse 方法. 6,sql 中ID自动增长,查询31到40条记录 ...

  2. windows消息机制详解(转载)

    消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了.例如,单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.消息本身是作为一个记录传递给应用程序的 ...

  3. 前端小知识~~关于css3新增知识~~归纳总结

    1.新增选择器 E:nth-last-child(n) E:nth-of-type(n) E:nth-last-of-type(n) E:last-child E:first-of-type E:on ...

  4. BeautifulSoup Some characters could not be decoded, and were replaced with REPLACEMENT CHARACTER.

    BeautifulSoup很赞的东西 最近出现一个问题:Python 3.3 soup=BeautifulSoup(urllib.request.urlopen(url_path),"htm ...

  5. 游标cursor

    if exists(select * from sys.objects where name='info_one') drop table info_one go create table info_ ...

  6. 【hihoCoder】1148:2月29日

    问题:http://hihocoder.com/problemset/problem/1148 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 思路: 1. 将问题转换成求两个日 ...

  7. Smart3D系列教程4之 《案例实战演练1——小物件的照片三维重建》

    一.前言 Wish3D出品的Smart3D系列教程已经推出3讲了,分别是关于倾斜摄影三维建模原理应用.照片采集技巧.Smart3D各个功能模块的作用,它们都是围绕Smart3D建模软件进行的讲解.那么 ...

  8. Jmeter之参数化

    Jmeter参数化分为两类,一类是在badboy录制脚本时进行参数化,二是再Jmeter里进行参数化 一:badboy录制脚本时进行参数化的步骤 1.脚本录制成功后->在左下角,点击variab ...

  9. 元素的click与dblclick

    JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间,是用户或浏览器自身执行的某种动作.诸如click.load.mousemover,都是事 ...

  10. sqlalchemy(二)高级用法

    sqlalchemy(二)高级用法 本文将介绍sqlalchemy的高级用法. 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此需要在address上增 ...