WebEditor系列3 (Range)

Step4. 了解 Range 对象:

Range表示网页中的一块选择区域。

比如FireFox在页面中选取了3段文字,那么就会有相对应的3个Range对象

Range可以用 Document 对象的 createRange方法创建,也可以用Selection对象的getRangeAt方法取得。另外,可以通过构造函数 Range() 来获得一个 Range 。

详细参见 developer.mozilla.org Range

Range 的主要属性(只读):

属性 用途
Range.collapsed 返回一个用于判断 Range 起始位置和终止位置是否相同的布尔值。
Range.commonAncestorContainer 返回包含 startContainer 和 endContainer 的最深的节点。
Range.endContainer 返回包含 Range 终点的节点。
Range.endOffset 返回 endContainer 中表示Range终点位置的数字。
Range.startContainer 返回包含 Range 开始的节点。
Range.startOffset 返回 startContainer 中表示 Range 起始位置的数字。

他们之间的关系如下图:

Selection 的主要方法:

属性 参数 用途
Range.setStart(startNode, startOffset) dom,number 设置 Range 的起点。
Range.setEnd(endNode, endOffset) dom,number 设置 Range 的终点。
Range.setStartBefore(referenceNode) dom 以其它节点 ( Node)为基准,设置 Range 的起点。
Range.setStartAfter(referenceNode) dom 以其它节点为基准,设置 Range 的始点。
Range.setEndBefore(referenceNode) dom 以其它节点为基准,设置 Range 的终点。
Range.setEndAfter(referenceNode) dom 以其它节点为基准,设置 Range 的终点。
Range.selectNode(referenceNode) dom 设定一个包含节点和节点内容的 Range 。
Range.selectNodeContents(referenceNode) dom 设定一个包含某个节点内容的 Range 。
Range.collapse(bool) bool 向指定端点折叠该 Range 。
--- --- ---
Range.cloneContents() dom 返回 Range 当中节点的文档片段(DocumentFragment)。
Range.deleteContents() 从文档(Document)中移除 Range 中的内容。
Range.extractContents() 把 Range 的内容从文档树移动到文档片段中。
Range.insertNode(dom) dom 在 Range 的起点处插入节点。
Range.surroundContents(dom) dom 将 Range 的内容移动到一个新的节点中。
Range.cloneRange() 返回拥有和原 Range 相同端点的克隆 Range 对象。
Range.toString() 把Range内容作为字符串返回。

demo 点击下文按钮:

btn1.onclick = function() {
    var select = document.getSelection();
    if (select.rangeCount) {
        var range = select.getRangeAt(0);
        var frag = range.cloneContents();
        txt.value = frag.textContent;
    }
}

btn2.onclick = function() {
    var select = document.getSelection();
    var range = document.createRange();
    select.removeAllRanges(); //chrome 只支持 一个区域
    var spanTextNode = span1.childNodes[0];
    range.setStart(spanTextNode, 0);
    range.setEnd(spanTextNode, spanTextNode.length);
    select.addRange(range);
}

btn3.onclick = function() {
    var select = document.getSelection();
    if (select.rangeCount) {
        var range = select.getRangeAt(0);
        var frag = range.extractContents();

        var colorNode = document.createElement("color");
        colorNode.style.color = "red";
        colorNode.innerText = frag.textContent;
        range.insertNode(colorNode);
    }
}

selection 对象是对网页中所有选择区域的一个统筹管理者, 其实像collapse deleteFromDocument 等方法是不应该放在 selection 中的 因为range对象已经很好地实现了这些功能(下篇 会介绍 range 对象) 因为FireFox允许多个 range 而 Chrome IE不允许.所以在这里 API的设计就产生了分歧. 为了互相兼容,所以现在 selection 也具备了 range的一些功能.

range.setStart(startNode, startOffset):

设置 Range 的起点

使用的时候要注意,如果 startNode 是一个文本节点则 则光标会停在这个文本节点从左往右数第 startOffset 那个字的位置那.,

如果 startNode 是一个一般dom节点 则光标会停在 parentNode.childNodes[startOffset] 那个节点的开头位置.

range.setEnd(endNode, endOffset):

设置 Range 的结束点

使用的时候要注意,如果 startNode 是一个文本节点则 则光标会停在这个文本节点从左往右数第 endOffset 那个字的位置那.,

如果 startNode 是一个一般dom节点 则光标会停在 parentNode.childNodes[endOffset] 那个节点的开头位置.

range.setStartBefore(dom) | range.setStartAfter(dom):

作用: 以其它节点(dom)为基准,设置 Range 的起点位置。

这个2个API很相似,他们都是用来设置一个选择区域的起始点的. 区别在于你想把开始位置放在dom的尖括号里面还是外面

setStartBefore是外边, setStartAfter是里面:

range.selectNode(dom):

作用:选中一个节点(参数 dom 全部, 相当于 range.setStartBefore(dom) + range.setEndAfter(dom))

range.selectNodeContents(dom):

作用:选中一个节点的内容 ,(参数 dom 的内容, 相当于 range.setStartAfter(dom) + range.setEndBefore(dom))

range.collapse(bool):

作用:折叠一段选中区域,(简单来说就是 定位光标到选中区域的开头或者结尾)

true 定位到开头.

false 定位到结尾.

range.cloneContents():

作用: 以DocumentFragment形式返回你选中的区域内容.

比如你选中了以下区域:

则返回的是

o
<p>je</p>

range.deleteContents():

作用: 删除你选中的区域. 返回 undefined;

这个应该不需要解释...

range.extractContents():

作用: 和 range.deleteContents() 类似, 只不过他会把你选中的节点以 DocumentFragment 的形式 return 出来.

range.insertNode(dom):

作用: 在选择区域的开始的位置,插入dom节点.

range.insertNode(dom):

作用: 将 Range 的内容移动到一个新的节点中。 感觉比较少用.

range.cloneRange(dom):

作用: 返回拥有和原 Range 相同端点的克隆 Range 对象。

range.toString(dom):

作用: 把Range内容作为字符串返回。 即去除多余的 尖括号 等标记.

留言:

称呼:*

邮件:

网站:

内容: