写在前面:

网上有各种富文本编辑器,微博分享等操作,这些功能非常实用,他们就是使用 range,selection 对象来实现的,这两个对象偏冷门,不涉及编辑器一般用不到,range 对象是对选区的操作,选区是鼠标在页面上按下,然后拖动选择的内容,range 对象就是对这个选区的操作;selection 是当前活动区的操作对象,selection 对象下面可以有多个 range 对象;这篇文章写的是标准的 selection和 range,小于 IE 9 的旧版本不在讨论范围内;

先来看一下 W3C 文档上的 range 对象的基本属性:

collapsed:返回一个用于判断 Range 起始位置和终止位置是否相同的布尔值。

commonAncestorContainer:返回包含 startContainer 和 endContainer 的最深的节点。

endContainer:返回包含 Range 终点的节点。

endOffset:返回 endContainer 中表示Range终点位置的数字。

startContainer:返回包含 Range 开始的节点。

startOffset:返回 startContainer 中表示 Range 起始位置的数字。

注意:range 的这些属性都是只读的,看下面这张图,就明白这些属性是怎么回事了:

collapsed 为 flase,说明起始点和终点不在同一个位置,startOffset 是从0开始的,d 的索引是2,表示鼠标按下的位置,也就是 div 元素的字符开始算的,endOffset 是 4,是从 span 标签开始算的,i 字符在 span 标签立面的索引是4;

注意,他们总是从包裹字符的节点的开始字符计算的;

再来看下 range 的方法和解释:

setStart(node, index):设置 Range 的起点。
setEnd(node, index):设置 Range 的终点。
setStartBefore(node):以其它节点( Node)为基准,设置 Range 的起点。
setStartAfter():以其它节点为基准,设置 Range 的始点。
setEndBefore():以其它节点为基准,设置 Range 的终点。
setEndAfter():以其它节点为基准,设置 Range 的终点。
selectNode():设定一个包含节点和节点内容的 Range。
selectNodeContents():设定一个包含某个节点内容的 Range。
collapse():向指定端点折叠该 Range。

这个解释看了之后一脸蒙圈,我的感受是讲的不清楚,还是上图,加上我们的理解更直观:

setStart setEnd 方法:

JS 操作:

 // 创建新的 range 对象,设置 setStart setEnd
function setStartEnd() {
var box = document.getElementById('box');
if (document.createRange) {
var range = document.createRange();
var start = box.querySelector('span').firstChild;
var end = box.querySelector('p').firstChild; range.setStart(start, 2); // p 标签的第 2 个字符
range.setEnd(end, 3); // span 标签的 第 3 个字符
console.log(range.cloneContents()); // 打印 range 的内容
console.log(range); // 打印 range
}
}

选区的内容和打印 range 的结果:

这个例子可以看出来,startOffset 的位置在第一个 span 标签的 g 字符前面,endOffset 的位置在 p 标签的 p 字符前面;

需要注意的是,如果是跨标签的选区,没有匹配到结束标签时,会折叠选区,把起点的位置设置为结束点的位置;

看下这个例子,把开始节点设置为 p 标签,结束节点为 span 标签,从后面向前面选择:

var start = box.querySelector('p').firstChild; // 开始节点是 p
var end = box.querySelector('span').firstChild; // 结束节点是 span

打印出来的结果:

仔细检查会发现 collapsed: true,并且 startContainer 和 endContainer 是同一个元素,这说明这个 range 选区折叠了,所以操作的时候需要注意;

setStartBefore setEndBefore 方法:

JS 操作:

var box = document.getElementById('box');
if (document.createRange) {
var range = document.createRange();
var spans = box.querySelectorAll('span');
var refStart = spans[0].firstChild;
var refEnd = spans[1].firstChild; range.setStartBefore(refStart); // 设置 p 节点的开始位置为 range 的起点
range.setEndBefore(refEnd); // 设置 span 节点的开始位置为 range 的终点 console.log(range.cloneContents());
console.log(range);
}

这两个方法的作用是以参考节点的开始位置作为参考,来设置 range 的起点和结束点;

setStartAfter,setEndAfter 方法:

JS:

var box = document.getElementById('box');
if (document.createRange) {
var range = document.createRange();
var spans = box.querySelectorAll('span');
var refStart = spans[0].firstChild;
var refEnd = spans[1].firstChild; range.setStartAfter(refStart); // 设置 p 节点的结束位置为 range 的起点
range.setEndAfter(refEnd); // 设置 span 节点的结束位置为 range 的终点 console.log(range.cloneContents());
console.log(range);
}

这两个方法的作用是以参考节点的结束位置作为参考,来设置 range 的起点和结束点;

selectNode 方法:

JS:

var box = document.getElementById('box');
if (document.createRange) {
var range = document.createRange();
var span = box.querySelector('span').firstChild; range.selectNode(span); console.log(range.cloneContents());
console.log(range);
}

selectNode 方法的操作就是 range 选择整个节点的,默认 startOffset 是 0,endOffset 是1;

selectNodeContents 方法:

这个方法和 selectNode 很类似,区别是会默认把结束点的位置移到最后;

var box = document.getElementById('box');
if (document.createRange) {
var range = document.createRange();
var span = box.querySelector('span').firstChild; range.selectNodeContents(span); console.log(range.cloneContents());
console.log(range);
}

collapse 方法是设置折叠选区的,开始位置和结束位置相同,这么解释就清楚多了,作用是多用来设置光标的;

下一篇看一下 selection 对象的基本属性和用法;

编辑器开发之 Range 范围对象的学习的更多相关文章

  1. ios开发之OC基础-ios开发学习路线图

    本系列的文章主要来自于个人在学习前锋教育-欧阳坚老师的iOS开发教程之OC语言教学视频所做的笔记,边看视频,边记录课程知识点.建议大家先过一遍视频,在看视频的过程中记录知识点关键字,把把握重点,然后再 ...

  2. 编辑器开发之 Selection 对象的学习

    上一篇,介绍了 range 对象的一些属性和方法,了解了一些基本操作,现在来介绍另外一个重要的对象:selection 对象: MDN 的解释是:Selection 对象表示用户选择的文本范围或插入符 ...

  3. 李洪强iOS开发之OC[014] -对象的存储细节

    // //  main.m //  13 - 对象的存储细节 // //  Created by vic fan on 16/7/9. //  Copyright © 2016年 李洪强. All r ...

  4. 李洪强iOS开发之OC[018]对象和方法之间的关系

    // //  main.m //  18 - 对象和方法之间的关系 // //  Created by vic fan on 16/7/14. //  Copyright © 2016年 李洪强. A ...

  5. Winform开发之ADO.NET对象Connection、Command、DataReader、DataAdapter、DataSet和DataTable简介

    ADO.NET技术主要包括Connection.Command.DataReader.DataAdapter.DataSet和DataTable等6个对象,下面对这6个对象进行简单的介绍:(1)Con ...

  6. Android游戏开发之SurfaceView的使用-android学习之旅(五)

    SurfaceView和View的区别 View是在ui主线程中,直接响应用户的操作,以及任务的分发,但是任务比较复杂会出现阻塞. SurfaceView则不会出现这种问题,以为它直接从内存等取得图像 ...

  7. ios开发之OC基础-类和对象

    本系列的文章主要来自于个人在学习前锋教育-欧阳坚老师的iOS开发教程之OC语言教学视频所做的笔记,边看视频,边记录课程知识点.建议大家先过一遍视频,在看视频的过程中记录知识点关键字,把把握重点,然后再 ...

  8. 高效开发之SASS篇 灵异留白事件——图片下方无故留白 你会用::before、::after吗 link 与 @import之对比 学习前端前必知的——HTTP协议详解 深入了解——CSS3新增属性 菜鸟进阶——grunt $(#form :input)与$(#form input)的区别

    高效开发之SASS篇   作为通往前端大神之路的普通的一只学鸟,最近接触了一样稍微高逼格一点的神器,特与大家分享~ 他是谁? 作为前端开发人员,你肯定对css很熟悉,但是你知道css可以自定义吗?大家 ...

  9. ArcGIS Engine开发之旅09--几何对象和空间参考

    原文:ArcGIS Engine开发之旅09--几何对象和空间参考 1.Geometry  Geometry 是 GIS 中使用最为广泛的对象集之一,用户在创建.删除.编辑和进行地理分析的时候,就是处 ...

随机推荐

  1. CSS+DIV定位分析(relative,absolute,static,fixed)

    在用CSS+DIV进行布局的时候,一直对position的四个属性值relative,absolute,static,fixed分的不是很清楚,以致经常会出现让人很郁闷的结果.今天研究了一下,总算有所 ...

  2. 近期写js库中遇到的一个判别的问题

    最近在写一个自己的js库,正写到数组包,在里面定义了一个排序,只对纯数字数据进行排序的方法,但是在测试的时候发现一个很诡异的问题,那就是传入一个对象的时候,它没有返回erroemsg而是返回了对象,上 ...

  3. Python+Selenium+PIL+Tesseract真正自动识别验证码进行一键登录

    Python 2.7 IDE Pycharm 5.0.3 Selenium:Selenium的介绍及使用,强烈推荐@ Eastmount的博客 PIL : Pillow-3.3.0-cp27-cp27 ...

  4. Java Script 学习笔记 (一) 基础

    1. 设置变量 const: 赋常量,不可更改. let :设置可更改变量. ES6 中推荐使用let 而不是var. Let 和var的区别 : let 将变量的作用域限定在当前{}中, var 定 ...

  5. HashMap和LinkedHashMap的区别

    参考:https://blog.csdn.net/a822631129/article/details/78520111 java为数据结构中的映射定义了一个接口java.util.Map;它有四个实 ...

  6. bzoj4067 [Ctsc2015]gender

    好神的一道题啊! 我们发现题目中的ln的贡献非常傻逼,但是我们可以发现这个东西的取值只有40个左右,于是我们可以枚举他! 枚举完了对于题里的贡献就是一个普通的最小割,采用的是文理分科的思想,与S连代表 ...

  7. 【游戏开发】Excel表格批量转换成lua的转表工具

    一.简介 在上篇博客<[游戏开发]Excel表格批量转换成CSV的小工具> 中,我们介绍了如何将策划提供的Excel表格转换为轻便的CSV文件供开发人员使用.实际在Unity开发中,很多游 ...

  8. Android圆形头像,拍照后“无法加载此图片”的问题解决(适配Android7.0)

    Feature: 点击选择拍照或者打开相册,选取图片进行裁剪最后设置为圆形头像. Problem: 拍好照片,点击裁剪,弹Toast"无法加载此图片". Solution: 在裁剪 ...

  9. LeetCode算法题-Unique Morse Code Words(Java实现)

    这是悦乐书的第318次更新,第339篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第186题(顺位题号是804).国际莫尔斯电码定义了一种标准编码,其中每个字母映射到一系 ...

  10. 使用Keepalived构建LVS高可用集群

    LVS的DR模型配置+Keepalive部署 介绍 下图为DR模型的通信过程,图中的IP不要被扑结构中的IP迷惑,图里只是为了说明DR的通信原理,应用到本例中的拓扑上其工作原理不变. 拓扑结构 服务器 ...