• 节点树和元素树知识整理


        我们在阅读JS高级程序设计的时候,提到了节点树的概念。比如说:

    elem.parentNode---找elem的父节点

    elem.childNodes---找elem的所有的直接子节点;

    elem.nextSibling---找elem的下一个同辈节点‘;

    elem.previousSibling---找elem的上一个同辈节点

    因为childNodes包含看不见的空格文本,还有注释等内容,所以使用起来不是太方便。

    因此,JS又重新引入了元素树的概念。这个的话,在我们实际应用中,用的比较普遍。

    元素树:仅仅包含元素节点的树结构,不是一颗新树,尽是节点数的子集;
    elem.parentElement 找节点的父元素;
    elem.children返回节点的所有子元素;
    elem.firstElementChild 第一个直接子元素;
    elem.lastElementChild 最后一个直接字元素;
    elem.previousElementSibling 找elem的前一个兄弟元素;
    elem.nextElementSibling 找elem的下个兄弟元素;

    在这里,我们介绍一个笔试题:

    遍历一个指定父节点下的所有后代节点,这里需要明确一点,就是所有的后代节点都需要遍历到:

     1 <script type='text/javascript'>
     2          function getChildren(parent){
     //如果当前父节点不是文本节点,就输出标签名,否则输出文本内容
    3 console.log(parent.nodeType!=3?parent.nodeName:parent.nodeValue);
    //获得父节点的所有直接子节点
    4 var children = parent.childNodes;
    //遍历children中每个节点
    5 for(var i =0,len =children.length;i<len;i++){
    //Step2: 对当前子节点调用getChildren
    6 getChildren(children[i]);//这里使用递归的调用方法; 7 //console.log(children[i].nodeType !=3?children[i].nodeName:children[i].nodeValue); 8 } 9 } 10 getChildren(document.body); 11 </script>

    这里我们需要知道一个算法-----深度优先遍历:当同时有兄弟节点和子节点的时候,总是优先遍历子节点。

    上面代码的遍历顺序,就是优先遍历子节点。

    我们在高性能JS这本书学到过,就是递归的运行效率没有迭代的运行效率高,所以,我们优化的话,一般都需要把递归的循环优化成迭代的循环。

    上面的例子如何修改呢,这里我们要提到一个新的概念,那就是:

    NodeIterator 对象,可以对 DOM 树进行深度优先的搜索

    创建 NodeIterator 对象,需要使用 document 对象的 createNodeIterator() 方法,该方法接收四个参数:

    • root,搜索开始的节点
    • whatToShow,一个数值代码,表示哪些节点需要搜索
    • filter,NodeFilter 对象,决定忽略哪些节点
    • entityReferenceExpansion,布尔值,表示是否需要扩展实体引用

    whatToShow 参数:

    • NodeFilter.SHOW_ALL,显示所有节点
    • NodeFilter.SHOW_ELEMENT,元素节点
    • NodeFilter.SHOW_ATTRIBUTE,属性节点
    • NodeFilter.SHOW_TEXT,文本节点
    • NodeFilter.SHOW_CDATA_SECTION,![CDATA] 节点
    • NodeFilter.SHOW_ENTITY_REFERENCE,实体引用节点(&quot
    • NodeFilter.SHOW_ENTITY,实体元素节点(<!ENTITY foo "foo">
    • NodeFilter.SHOW_PROCESSING_INSTRUCTION,PI 节点
    • NodeFilter.SHOW_COMMENT,XML 注释节点
    • NodeFilter.SHOW_DOCUMENT,文档顶层节点
    • NodeFilter.SHOW_DOCUMENT_TYPE,DTD 节点
    • NodeFilter.SHOW_DOCUMENT_FRAGMNT
    • NodeFilter.SHOW_NOTATION

    我们重新修改后的代码如下:

     1 function getChildren(parent){
     2                  //获取NodeIterator对象
     3                   var t = document.createNodeIterator(parent,NodeFilter.SHOW_ALL,null,false);
     4                   //循环遍历对象的下一个节点;
     5                   while(true){
     6                       var node = t.nextNode();
     7                       //节点不为空,就一直循环遍历下去;直到为null,才中断循环;
     8                       if(node !=null)
     9                           console.log(node.nodeType!=3?node.nodeName:node.nodeValue)
    10                       else
    11                             break;
    12                   }
    13              }
    14                    getChildren(document.body);

    这种方式的话,使用起来更加的方便,简单。

  • 相关阅读:
    Python爬虫入门教程 45-100 Charles抓取兔儿故事-下载小猪佩奇故事-手机APP爬虫部分
    Python爬虫入门教程 44-100 Charles的安装与使用-手机APP爬虫部分
    Python爬虫入门教程 42-100 爬取儿歌多多APP数据-手机APP爬虫部分
    Python爬虫入门教程 43-100 百思不得姐APP数据-手机APP爬虫部分
    Python爬虫入门教程 41-100 Fiddler+夜神模拟器+雷电模拟器配置手机APP爬虫部分
    Python爬虫入门教程 40-100 博客园Python相关40W博客抓取 scrapy
    Python爬虫入门教程 39-100 天津市科技计划项目成果库数据抓取 scrapy
    Python爬虫入门教程 38-100 教育部高校名单数据爬虫 scrapy
    Python爬虫入门教程 37-100 云沃客项目外包网数据爬虫 scrapy
    Python爬虫入门教程 36-100 酷安网全站应用爬虫 scrapy
  • 原文地址:https://www.cnblogs.com/xuzhudong/p/6624213.html
Copyright © 2020-2023  润新知