zoukankan      html  css  js  c++  java
  • DOM2级遍历和范围

    DOM遍历

    现有用于辅助完成顺序遍历DOM结构的类型有两个,NodeIterator和Treewalker。在于DOM兼容的浏览器中,都可以访问这两个对象,IE不支持DOM遍历,使用下列代码可以检测浏览器对DOM2级遍历的支持情况:

    1 var supportTraversals = document.implementation.hasFeature('Traversal','2.0');
    2 var supportNodeIterator = (typeof document.createNodeIterator == 'function');
    3 var supportTreeWalker = (typeof document.createTreeWalker == 'function');

    遍历是以给定节点为根,不可能向上超出DOM根节点,以下面的HTML页面为例:

     1 <html>
     2     <head>
     3         <title>遍历</title>
     4     </head>
     5     <body>
     6         <div>
     7             <p>Hello</p>
     8         </div>
     9         <span>world</span>
    10     </body>
    11 </html>

    遍历的顺序如下:1.Document -> 2. HTML ->3.head -> 4.title ->5.Text 遍历

                                                              -> 6.body -> 7.div -> 8.p -> 9.Text Hello

                                                                             -> 10.span ->11.Text World

    NodeIterator

    NodeIterator可以用document.createNodeIterator()方法创建其实例,这个方法接受4个参数,分别如下:

              root: 作为搜索树的起点

              whatToShow:表示要访问哪些节点的数字代码

              filter:表示接受或拒绝某一个特定的Node

              entityReferenceExpansion:Bool变量,表示是否要扩展实体引用,在HTML中无用,直接设为false即可。

    看以下示例:

    1 var filter = {
    2     acceptNode:function(node){
    3         return node.tagName.toLowerCase() == 'p'?NodeFilter.FILTER_ACCEPT :NodeFilter.FILTER_SKIP;
    4     }
    5 };
    6 var iterator = document.createNodeIterator(document,NodeFilter.SHOW_ELEMENT,filter,false);

    这个iterator就是对页面中所有的p遍历。可以用iterator.nextNode()和iterator.previousNode()来访问各个遍历,在访问到根节点时,会返回null。

    TreeWalker

    TreeWalker可以说是NodeIterator的高级版本,它在前面的nextNode和previousNode以外,还提供了一系列方法,部分如下:

             parentNode():遍历到当前节点的父节点;

             firstChild():遍历到当前节点的第一个子节点;

             lastChild():遍历到当前节点的最后一个节点;

             nextsibling():遍历到当前节点的下一个同辈节点;

             perviousSibling():遍历到当前节点的前一个同辈节点;

    创建TreeWalker和使用方法如下例子:

    1 var filter = function(node){
    2     return node.tagName.toLowerCase() == 'p'?NodeFilter.FILTER_ACCEPT :NodeFilter.FILTER_SKIP;
    3 }
    4 var walker = document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT,filter,false);
    5 var node = walker.nextNode();
    6 while(node != null){
    7     console.log(node.tagName.toLowerCase());
    8     node = walker.nextNode();
    9 }

    其中,NodeIterator中的filter也可以如上的形式编写。

    范围

    DOM2级定义了范围接口,可以选择一个文档的一个区域,而不用考虑结点界限。可以用createRange()创建范围,在兼容DOM的浏览器中,这个是属于document,可以用hasFeature检测是否支持

    1 var supportRange = document.implementation.hasFeature('Range','2.0');
    2 var supportRange2 = (typeof document.createRange == 'function');

    若支持,就可以用document.createRange()来创建范围了

    创建范围后,就可以用selectNode()和selectNodeContents()来选择范围了,selectNode选择的是整个结点,而selectNodeContents选择的是该节点的所有子节点,以下面的HTML为例:

     1 <html>
     2     <head>
     3         <title>遍历</title>
     4     </head>
     5     <body>
     6         <div>
     7             <p>Hello</p>
     8         </div>
     9         <span>world</span>
    10     </body>
    11 </html>

     我们用以上的HTML创建范围:

    1 var div = document.getElementsByTagName('div')[0],
    2     range = document.createRange(),
    3     range2 = document.createRange();
    4 range.selectNode(div);
    5 range2.selectNodeContents(div);

    range的范围:<div><p>Hello</p></div>

    range2的范围:<p>Hello</p>

    当然,要创建精细复杂的选择,就可以使用setStart()和setEnd(),都接受两个参数,一个参照结点和偏移量

    选择DOM范围后就需要进行DOM操作了,在操作之前,我们需要考虑一个问题,就是精细操作以后,如果我选择的是一个结点的一部分(按上个例子,我选择了<p>Hel),如果进行删除操作,那么不是文档不完整了?其实在选择范围后,在后台会动态补上缺失的标签(按刚才的会补充成<p>Hel</p><p>llo</p>),这样就可以无误的进行操作DOM了。

    操作的方法有deleteContents()—删除文档区域

                     extractContents()—提取文档区域,原始的在文档中的内容会删除

                     insertNode()—向范围选取开始处插入一个节点

                     cloneContents()—复制范围对象,返回一个副本

    通过这些方法,就可以简单操作DOM范围了

    1 var div = document.getElementsByTagName('div')[0],
    2     range = document.createRange();
    3 range.selectNode(div);
    4 range.deleteContents();
  • 相关阅读:
    PHP面向对象之接口 (interface)
    防止继承和覆盖(PHP类)
    对PHP中类、继承、抽象的理解(个人总结)
    AngularJS directive 分页,待续...
    facade(外观)模式
    command (命令)模式
    javascript设计模式 富有表现力的javascript
    AngulatJS $directive compile
    directive talks to controller
    testing
  • 原文地址:https://www.cnblogs.com/cyITtech/p/DOM_rangeAndSelect.html
Copyright © 2011-2022 走看看