document_object_model_range

来源:互联网 发布:数组里的频率最高点 编辑:程序博客网 时间:2024/06/06 20:43
===== 介绍 =====
Range标识了一定范围Document,DocumentFragment或Attr的内容。它是连续的,可以通过选择一对边界点内的内容描述。

并不是每一个Range都对应一个选择,而每一次选择都会返回一个Range。

Range接口提供了比DOM对节点操作更高层次的接口,当然这些最后都转化成了节点的操作,这意味着Range接口可以直接由节点操作完成。


===== 定义和表示 =====
==== 位置(Position) ====
文档的两种表达方式,包括标记的源码表示和DOM树结构表示。以下是与Position相关概念的定义。

Range是由边界点(boundary-point)组成的,而边界点由容器(container)和偏移(offset)定义。容器的父节点是边界点的父容器(ancestor container)。如果容器是Attr, Document, DocumentFragment, Element或EntityReference节点,那么偏移就在容器的子节点中。如果容器是CharacterData, Comment或ProcessingInstruction,那么偏移是容器中字符串间隙。

一个Range的两个边界点必须拥有相同的父容器,即是Document, DocumentFragment或Attr。共同的父容器称为Range的根容器(root container),包含Range根容器的DOM树称为Range的内容树(context tree)

边界点不能在标签内部。

{{:tech:rangeexample.gif?|}}

Range与容器和偏移相关的属性

  readonly attribute Node startContainer;
  readonly attribute long startOffset;
  readonly attribute Node endContainer;
  readonly attribute long endOffset;
==== 选择和部分选择(Selection and Partial Selection) ====
选择的内容可以包括连续节点或者是文本。

当节点被部分选择时,它仅仅是一个边界点的父容器。
==== 规范 ====
本文中document都是通过文本方式表示,通过粗体表示被Range选中的内容。

<FOO>A**BC<BAR>DEF**</BAR></FOO>

如果边界点重合,则使用^表示。

<FOO>A^BC<BAR>DEF</BAR></FOO>
===== 构建Range ====
Range可以通过DocumentRange的接口createRange创建。

  interface DocumentRange {
    Range createRange();
  }

初始的Range两个边界点都指向文档的起始点。被特定文档创建的Range只能选择该文档的内容。
===== 重设位置 =====
Range提供以下接口重设边界点。
  void setStart(in Node parent, in long offset)
                        raises(RangeException);
  void setEnd(in Node parent, in long offset)
                raises(RangeException);
下面方式可以通过相对位置重设边界点,此时容器成为了node的父节点。
  void setStartBefore(in Node node);
                              raises(RangeException);
  void setStartAfter(in Node node);
                       raises(RangeException);
  void setEndBefore(in Node node);
                      raises(RangeException);
  void setEndAfter(in Node node);
                     raises(RangeException);
以下方法可以设置Range在起始边界点还是在结束边界点collapse
  void collapse(in boolean toStart);
以下属性检测Range是否发生collapse
  readonly attribute boolean collapsed;
以下方法选定特定节点或其内容
  void selectNode(in Node n);
  void selectNodeContents(in Node n);

===== 比较边界点 =====
  short compareBoundaryPoints(in CompareHow how, in Range sourceRange) raises(RangeException);
CompareHow只能是以下四个值
  * START_TO_START
  * START_TO_END
  * END_TO_END
  * END_TO_START
结果返回-1,0,1分别对应位置在前面,等于,后面

对于边界点位置的比较可能有几种情况
  * 容器相同
  * 它们的容器不在节点树同一个高度上,同时也不是包含关系
  * 它们的容器在节点树上存在包含关系
针对不同情况,先后关系的比较有不同定义。同时需要注意的是,在文本表示的文档上具有相同位置的边界点,可能在节点树中有不同的含义。
===== 删除内容 =====
  void deleteContents();
以下是示例

  * <FOO>A**B<MOO>CD</MOO>**CD</FOO>  ⇒  <FOO>A^CD</FOO>

  * <FOO>A<MOO>B**C</MOO>D**E</FOO>  ⇒  <FOO>A<MOO>B</MOO>^E</FOO>

  * <FOO>X**Y<BAR>Z**W</BAR>Q</FOO>  ⇒  <FOO>X^<BAR>W</BAR>Q</FOO>

  * <FOO><BAR1>A**B</BAR1><BAR2/><BAR3>C**D</BAR3></FOO>  ⇒  <FOO><BAR1>A</BAR1>^<BAR3>D</BAR3>
===== 提取内容 =====
  DocumentFragment extractContents();

  * <FOO>A**B<MOO>CD</MOO>**CD</FOO>  -->  B<MOO>CD</MOO>
  * <FOO>A<MOO>B**C</MOO>D**E</FOO>  -->  <MOO>C<MOO>D
  * <FOO>X**Y<BAR>Z**W</BAR>Q</FOO>  -->  Y<BAR>Z</BAR>
  * <FOO><BAR1>A**B</BAR1><BAR2/><BAR3>C**D</BAR3></FOO> -->  <BAR1>B</BAR1><BAR2/><BAR3>C</BAR3>
===== 复制内容 =====
  DocumentFragment cloneContents();
===== 插入内容 =====
  void insertNode(in Node n) raises(RangeException);
在text节点插入节点会导致text节点的分裂
===== 装饰内容 =====
  void surroundContents(in Node newParent);
示例
  Before:
    <BAR>AB<MOO>C</MOO>DE</BAR>
 
  After surroundContents(FOO):
    <BAR>A<FOO>B<MOO>C</MOO>D</FOO>E</BAR>
当Range包含部分选择的非文本节点时,会产生异常
===== 其他成员 =====
克隆Range对象
  Range cloneRange();
获得边界点的最近父容器
  readonly attribute Node commonAncestorContainer;
获得选中对象的字符表示
  DOMString toString();
===== 文档变化时Range的修改 =====
文档变化时Range所作的变化依照以下两个原则
  * 所有的Range依然有效
  * 尽可能选择相同的区域
事实上,伴随文档改变导致的Range改变可以看成是一系列的Range操作,包括插入和删除。
==== 插入 ====
仅当插入节点和边界点拥有相同容器并且偏移小于边界点偏移时,才产生Range边界点的修改
==== 删除 ====
详细见[[http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Deletions]]示例
===== 相关资料 =====
W3C DOM-Level-2-Traversal-Range ranges [[http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html]]