Range对象

Range表示HTML文档的一部分内容,它可以在任何点开始和结束,最常见的Range就是用户选择的一段文本。通过Range对象,你可以找到开始点和结束点,你可以复制或者删除它,或者替换成另一段文本,甚至是一段HTML代码。


比如用户从下面的文本中选择了一段:

选中的这段文本跨越了好几个HTML元素,而且你会发现,这段选中的文本是极不规范的HTML代码,比如第一行没有<p>,最后一行没有</li>。


还好,所有浏览器都会自动补全:


获得用户选择区域

function getUserSelection(){
    if(window.getSelection){
        return window.getSelection();
    }else if(document.selection){
        return document.selection.createRange();
    }
}

W3C:用户选择区域是Selection对象

    IE:用户选择区域是TextRange对象 


获得用户选择的内容

var userSelection = getUserSelection(), 
    selectedText = userSelection.text || userSelection.toString();


通过Selection对象创建Range对象

function getRange(selection){
    if(selection.getRangeAt){
        return selection.getRangeAt(0);
    }else{//不支持getRangeAt的情况
        var range = document.createRange();
        range.setStart(selection.anchorNode, selection.anchorOffset);
        range.setEnd(selection.focusNode, selection.focusOffset);
        return range;
    }
}

IE调用getUserSelection()方法获得的就是一个TextRange对象,所以不需要再创建Range对象了。 


通过编程的方式创建Range对象

如果浏览器不支持getRangeAt()方法,比如Safari1.3,我们需要先创建一个新的Range对象,而它必须包含用户当前选中的区域。

首先创建一个空的Range对象:

var range = document.createRange();


为了把它插进文档树中,我们需要设置开始点和结束点:

range.setStart(startNode, startOffset);
range.setEnd(endNode, endOffset);

  

下面给出IE和W3C方法创建Range对象的差异:

IE6/7/8W3C

IE6/7/8 只有 TextRange,在指定的对象上创建一个 TextRange 需要使用 'object.createTextRange()'。

注意不是任何类型的对象都可以创建 TextRange,只有 body 对象、button 对象、textarea 对象和 type='text' 的 input 对象才可以。

还可以通过 'document.selection.createRange()' 从当前的文本 selection 中得到一个 TextRange。

在标准浏览器中有两种方式创建Range对象:

1. 使用 'window.getSelection().getRangeAt(index)' 获得一组 Range 中指定的 Range

2. var range = document.createRange(),然后设置range的开始位置(setStart())和结束位置(setEnd())

 


属性:

属性说明
collapsed 返回一个boolean值,表示range的开始点和结束点是否为同一个位置。返回true表示没有包含任何内容,即DOM树中一个单独的点。这个属性是只读的,如需要操作它,请使用collapse方法。
commonAncestorContainer

返回包含 startContainer 和 endContainer 的最深的节点,这个属性是只读的,如需要操作它,请重新设置range的开始位置和结束位置。

  如果选择的是一段纯文本,如<span>1234</span>中的23,该属性为文本节点;

  如果选区跨越了节点,比如123<span>456</span>中的34,该属性为二者的父节点;

startContainer

返回包含range开始点的节点。这个属性是只读的,如需要操作它,请使用setStart方法。

  通常都是文本节点。

startOffset 返回一个number值,表示range在startContainer中的开始位置。startOffset有两种意思:如果 startContainer 是Text节点、Comment节点或CDATASection节点,startOffset是指从startContainer的开始位置到range的开始位置的偏移量;如果是别的节点类型,startOffset是指从startContainer的开始位置到range的开始位置的子节点数量。这个属性是只读的,如需要操作它,请使用setStart方法。
endContainer 返回包含range结束点的节点。这个属性是只读的,如需要操作它,请使用setEnd方法。
endOffset 返回一个number值,表示range在endContainer中的结束位置。



方法:

定位方法(用于设置Range的开始点和结束点)

方法说明
collapse(toStart) toStart是一个boolean值,true表示把Range collapse到开始位置,false表示把Range collapse到结束位置。
setStart(startNode, startOffset) 设置Range的开始位置。如果 startNode 是Text节点、Comment节点或CDATASection节点,startOffset是指从 startNode 的开始位置到range的开始位置的偏移量;如果是别的节点类型,startOffset是指从 startNode 的开始位置到range的开始位置的子节点数量。这个属性是只读的,如需要操作它,请使用setStart方法。
setEnd(endNode, endOffset) 设置Range的结束位置。
setStartBefore(referenceNode) 把Range开始位置的父节点设置为referenceNode。
setStartAfter(referenceNode) 把Range开始位置的父节点设置为referenceNode。
setEndBefore(referenceNode) 把Range结束位置的父节点设置为referenceNode。
setEndAfter(referenceNode) 把Range结束位置的父节点设置为referenceNode。
selectNode(referenceNode) 使Range包含referenceNode和它的子节点,把Range的开始位置和结束位置的父节点设置为referenceNode。
selectNodeContents(referenceNode) 使Range包含referenceNode的内容。startOffset 为 0, endOffset是子节点的数量 或者 referenceNode中的字符长度。



编辑方法(用于从Range中获取节点 和 修改Range的内容)

方法说明
cloneContents() 复制Range的节点,返回一个文档碎片。用addEventListener之类绑定的事件不会被复制,而onclick这样的直接写在元素attribute上的事件会被复制,元素的ID也会被复制,这有可能导致两个相同的ID。Partially selected nodes include the parent tags necessary to make the document fragment valid。
deleteContents() 删除Range的内容,这个方法不会返回包含删除内容的文档碎片。
extractContents() 把Range的内容装入一个文档碎片,规则和cloneContents()相同。
insertNode(newNode) 在Range的开始位置插入一个节点。如果 newNode 的插入位置是一个文本节点,这个文本节点会在插入位置进行分隔,也就是说最后是在两个文本节点之间进行插入。如果newNode是一个文档碎片,插入的是文档碎片的子节点。
surroundContents(newNode) 把Range的内容装入一个新节点,并把这个新节点放在Range的开始位置。surroundContents 等价于 newNode.appendChild(range.extractContents()); range.insertNode(newNode)。



其他方法:

方法说明
compareBoundaryPoints(how, sourceRange)

比较两个Range的边界点。

how:比较的方式,这是一个常量值:
  Range.END_TO_END -> 用 sourceRange 的结束点 与 当前Range的结束点 进行比较

  Range.END_TO_START -> 用 sourceRange 的结束点 与 当前Range的开始点 进行比较

  Range.START_TO_END -> 用 sourceRange 的开始点 与 当前Range的结束点 进行比较

  Range.START_TO_START -> 用 sourceRange 的开始点 与 当前Range的开始点进行比较

sourceRange:需要比较的Range

返回:-1, 0 或 1, 表示当前Range的边界点相对于sourceRange的边界点是在前,相等还是在后。

cloneRange() 返回一个和当前Range边界点完全相同的Range对象,这是值拷贝,非引用,所以改变其中一个不会影响另一个。
detach() 释放Range从而提高性能。调用 detach() 方法后,对这些属性的任何读操作都会抛出代码为 INVALID_STATE_ERR 的 DOMException 异常。
toString() 返回Range的文本。


兼容之道


MDN  PPK

posted @ 2011-11-02 22:59  越己  阅读(6734)  评论(2编辑  收藏  举报