zoukankan      html  css  js  c++  java
  • DOM 之Range(范围)

    -------《javascript高级程序设计》  12.4 范围  笔记-------

    DOM2级在Document类型中定义了createRange()方法,在兼容DOM的浏览器中,这个方法属于Document对象。可以使用HasFeature方法来检测浏览器是否支持范围

       var supportsRange = document.implementation.hasFeature(‘Range’, ‘2.0’)

       var alsoSupportsRange = (typeof document.createRange == ‘function’);

    一、如果浏览器支持Range,就可以使用createRange()来创建DOM范围

        var range = documemt.createRange();

        新创建的范围直接与创建它的文档关联在一起,不用用于其他文档。每一个范围由一个Range类型的实例表示。 它有很多属性及方法

      1. startContainer: 包含范围起点的节点(即选区中第一个节点的父节点)

      2. startOffset:  范围在startComtainer中起点的偏移量,如果startContainer是文本节点、注释节点或CDATA节点,那么startOffset就是范围起点之前的跳过的字符数量,否则,startOffset就是范围中第一个子节点的索引。

      3. endContainer  包含范围终点的节点(即选区中最后一个节点的父节点)

      4. endOffset: 范围在endContainer中节点的偏移量(与startOffset遵循相同的取值规则)

      5. commonAncestorContainer:  startContainer和endContainer共同的祖先节点在文档树中位置最深的那个

    二、用DOM范围实现简单选择

      选用的方法   selectNode()  或者selectNodeContents()

      1.这两个方法都接受一个参数,即一个DOM节点。但selectNode()方法选择整个节点,包括其子节点,而selectNodeContents()方法只是选择节点的子节点,

    range

    range

    ------为了更精细的控制将哪些节点包含在范围中,还可以使用下列方法 ------

      1. setStartBefore(refNode)  将范围的起点设置在refNode之前,因此refNode也就是范围选区中的第一个子节点,同时会将startContainer属性设置为refNode.parentNode,将startOffset属性设置为refNode在其父节点的childNodes集合中的索引

      2. setStartAfter(refNode)  将范围的起点设置在refNode之后,因此refNode也就不在范围之内了,其下一个同辈节点才是选区中的第一个子节点,同时会将startContainer属性设置为refNode.aprentNode,将startOffset属性设置为refNode在其父节点的childNodes集合中的索引加1;

      3. setEndBefore(refNode): 将范围的终点设置在refNode之前,因此refNode也就不在范围之内了,其上一个同辈节点才是范围选区中的最后一个子节点。同时会将endContainer属性设置为refNode.parentNode,将endOffset属性设置为refNode在其父节点的childNodes集合中的索引;

      4. setEndAfter(refNode) 将范围的终点设置 在refNode之后,因此refNode也就是范围选区中的最后一个子节点。同时会将endContainer属性设置为refNode.parentNode,将endOffset属性设置为refNode在其父节点的childNodes集合中的索引加1

    ----   用DOM范围实现复杂选择  -----

      要实复杂的范围就使用setStart() 和setEnd() 方法,这两个方法都接受两个参数:  一个参照节点和一个偏移量值

      setStart() 参照节点会变成startContainer,而偏移量值会变成startOffset

      setEnd()  参照节点会变成endContainer,偏移量会变成endOffset

      用这两个方法重写前面selectNode()与selectNodeContents()方法

    range

      setStart() 与setEnd()方法的运用

    range


    -----操作DOM范围中的内容-----

       在创建范围时,内部会为这个范围创建一个文档片段.范围所属的全部节点都被添加到了这个文档片段中,范围知道自身缺少哪些开标签和闭标签,它能够重新构建有效的DOM结构以便我们对其进行操作

      针对上面的例子,选区变为了 ‘llo’</b>wo 不是一个有效的DOM结构,但范围会自动添加缺少的,最终变成了

    <p><b>he</b><b>llo</b> wo rld</p>  范围内的文档片段是 

       无标题

    1. deleteContents()  从文档中删除范围所包含的内容,没有返回值

    2.extractContents()  也会从文档中移除范围选区,但会返回范围的文档片段,可以进行其他作用

    3.cloneContents()  创建范围对象的一个副本,然后在文档的其他地方插入该副本; 在调用方法之前,拆分的节点并不会产生格式良好的文档片段,换句话说,原始的HTMl在DOM被修改之前会始终保持不变

    4.insertNode(Node) 向范围选区的开始处插入一个节点

    5. surroundContents() 环绕范围内容插入内容, 接受一个参数,即环绕范围插入的节点

       在环绕范围插入内容时,后台会执行下列步骤

       1) 提取出范围中的内容(类似执行extractContent());

       2)   将给定节点插入到文档中原来范围所在的位置上;

       3)  将文档片段的内容添加到给定节点中;

    6.  折叠DOM范围

        就是范围中未选择文档的任何部分;collapse()方法来折叠范围,这个方法接受一个参数(布尔值) true 表示折叠到范围的起点,false表示折叠到范围的终点。要检测范围已经折叠完毕,可以检查collapsed属性

        检测某个范围否处于折叠状态,可以帮我们确定范围中的两个节点是否紧密相邻。  将一个范围设置第一个节点的终点,另一个范围设置为第二个节点的起点,如果两个节点是相邻了 这个范围就折叠完毕,

    7. 比较DOM范围

      在有多个范围的情况下,可以使用compareBoundaryPoints() 方法来确定这些范围是否有公共的边界(起点和终点)。这个方法接受两个参数:表示比较方式的常量值和要比较的范围。表示比较方式的常量值如下所示

      Range.START_TO_START(0) 比较第一个范围和第二个范围的起点

      Range.START_TO_END(1)  比较第一个范围的起点和第二个范围的终点

      Range.END_TO_END(2)  比较第一个范围和第二个范围的终点

      Range.END_TO_START(3) 比较第一个范围的终点和第一个范围的起点

      ---  compareBoundaryPoints()方法可能的返回值如下:

        如果第一个范围中的点位于第二个范围中的点之前,返回-1;

        如果两个点相等。返回0;

        如果第一个范围中的点位位于第二个范围中的点之后,返回1

    range

    8.cloneRange()  复制范围

    9. detach()  从创建范围文档中分离出该范围。从而让垃圾回收机制回收其内存

        range.detach();

        range = null

    --------------------------------ie的范围----------------------

    IE专有的文本范围(text range) 文本范围处理的主要是文本(不一定是DOM节点),通过<body>,<button>.<input>.<textarea> 等这几个元素可以调用createTextRange()方法来创建文本范围

    1.findText() 会找到第一次出现的给定文本,并将范围移过来环绕该文本。如果没找到文本,返回false,否则返回true

    textRange

       文本'hello’就被包含在范围之内。可以检测范围的text属性,来确认(这个属性返回范围中包含的文本),或者可以检查findText()的返回值

      还可以为findText()传入另一个参数,即表示向哪个方向继续搜索的数值,负值表示应该从当前位置向后搜索,正值表示从当前位置向前搜索

    2.moveToElementText() 接受一个DOM元素,并选择该元素的所有文本,包含HTML标签,(与selectNode类似)

       可以使用range的htmlText属性来取得范围的全部内容。包含HTMl和文本

    3. parentElement()  (与commonAncestorContainer属性类似)

    -----使用IE范围实现复杂的选择---

    1. move()   moveStart()  moveEnd()  expend()  这四个方法都接受两个参数,移动单位和移动单位的数量

      移动单位是下列的一种字符串值

      ‘character’   逐个字符地移动

        'word’    逐个单词(一系列非空字符)地移动

       'sentence’ 逐个句子(一系列以句号、问号或叹号结尾的字符)地移动

      'textedit’ 移动到当前范围选区的开始或结束位置

      moveStart()  moveEnd()  可以移动范围的起点和终点,移动的副度同单位数量指定 (正值表示缩小范围,负值表示增大范围)

      expand()  可以将范围规范化。(将任何部分选择的文本全部选中)

      move() 方法会首先折叠当前范围(让起点和终点相等),然后再将移动指定的单位数量

       调用move()之后,范围的起点与终点相同,因此必须再使用moveStart() 或moveEnd()创建新的选区

    2.操作范围中的内容可以使用text属性或pasteHTML()方法,

       text属性是可读写的 ,可以获取范围内的文本,也可以设置范围内的文本

       pasteHTMl()  方法可以设置范围内的HTMl,插入HTMl时可能会导致格式不正确的HTMl存在(范围选取时截取了标签)

    3. 折叠范围

      collapse()  参数为布尔值,true  折叠到起点。false折叠到终点

      IE没有collapsed属性来检测是否折叠完毕,但可以使用boundingWidth属性。该属性返回范围的宽度(以像素为单位),折叠完毕后boundingWidth返回值为0  (boundingTop,boundingHeight,boundingWidth,boundingLeft

    4. 比较IE范围

      compareEndPoints() 方法 (与DOM范围中的compareBoundaryPoints()方法类似)  接受两个参数:比较的类型和要比较的范围。比较类型的取值范围是下列几个字体串

      'startToStart’ , ‘startToEnd’ ‘EndtoEnd’ ‘EndToStart’

    compareEndPoints()方法返回值(与DOM的compareBoundaryPoints()方法一样)

    如果第一个范围的边界位于第二个范围的边界前面,返回-1;

    如果两个边界相同,返回0;

    如果第一个范围的边界位于第二个边界的后面,返回1

     IE中还有两个方法,用于比较范围

      isEqual()  确定两个范围是否相等

      inRange()  用于确定一个范围是否包含另一个范围

    5.复制IE范围

      duplicate()方法可以复制文本范围

  • 相关阅读:
    Visual C++6.0 调用Visual Basic 6.0写的Microsoft Communications Control(ActiveX)的使用疑难及解决办法
    Associating Icons with a Category 与 恶作剧软件 有关系吗?
    WPF/Silverlight Button Styles and Templates
    Notepad++ 备忘录一
    冥思苦想,木疙瘩也能崩出个豆:扯一下各大软件的用户体验
    生活小窍门。
    Bug验证:.Net 4 下,貌似发现一个bug。如果是真,.Net组的员工该打屁股。
    两台硬件和软件配置完全相同的机器A和B,现在要用系统自带的Copy功能把A上的一个文件,复制到B上。在哪台机器上执行程序,效率更高?
    WPF 遍历 DataGrid 每行的控件
    IE ActiveX Control 和RIA
  • 原文地址:https://www.cnblogs.com/fsy0718/p/3354587.html
Copyright © 2011-2022 走看看