美文网首页程序员web之路让前端飞
【十七】浏览器DOM:你知道HTML的节点有哪几种吗?

【十七】浏览器DOM:你知道HTML的节点有哪几种吗?

作者: alanwhy | 来源:发表于2019-03-25 22:55 被阅读10次

    文档对象模型

    用来描述文档,特指HTML文档,同时又是一个“对象模型”,意味着它使用的是对象这样的概念来描述HTML文档。

    DOM API大致包含4个部分

    • 节点:DOM 树形结构中的节点相关API
    • 事件:触发和监听事件相关API
    • Range:操作文字范围相关API
    • 遍历:遍历DOM 需要的API

    节点

    节点.png
    Element: <tagname>...</tagname>
    Text: text
    Comment: <!-- comments -->
    DocumentType: <!Doctype html>
    ProcessingInstruction: <?a 1?>
    

    我们编写HTML代码运行后,就会在内存中得到这样一颗DOM树,HTML的写法会被转化成对应的文档模型,而我们则可以通过JS等语言来访问这个文档模型

    Node

    Node是DOM树继承关系的根节点,提供了一组属性,来表示在DOM树中的关系

    • parentNode
    • childNodes
    • firstChild
    • lastChild
    • nextSibling
    • previousSibling

    也提供了操作DOM树的API

    • appendChild
    • insertBefore
    • removeChild
    • replaceChild

    除此之外,Node还提供了一些高级的API

    • compareDocumentPosition 用于比较两个节点中关系的函数
    • contains 检查一个节点是否包含另一个节点
    • isEqualNode 检查两个节点是否完全相同
    • isSameNode 检查两个节点是否是同一个节点
    • cloneNode 复制一个节点

    DOM标准规定了节点必须从文档create方法创建出来。于是document有了这些方法

    • createElement
    • createTextNode
    • createCDATASection
    • createComment
    • createProcessingInstruction
    • createDocumentFragment
    • createDocumentType

    Element和Attribute

    Node提供了树形结构上节点相关的操作。
    Element表示元素,是Node的子类,既有子节点,又有属性

    对于DOM而言,Attribute和 Property是完全不同的定义

    把元素的Attrbute当作字符串来看,则有:

    • getAttribute
    • setAttribute
    • removeAttribute
    • hasAttribute
    • getAttributeNode
    • setAttributeNode

    查找元素

    document节点提供了查找元素的能力

    • querySelector(性能较低)
    • querySelectorAll
    • getElementById
    • getElementByName
    • getElementByTagName
    • getElementsByClassName

    遍历

    DOM还提供了NodeIterator和TreeWalker来遍历树,同时具有过滤功能

    NodeIterator的基本用法

    var iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT, null, false);
    var node;
    while(node = iterator.nextNode())
    {
        console.log(node);
    }
    

    以及TreeWalker的用法

    var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, false)
    var node;
    while(node = walker.nextNode())
    {
        if(node.tagName === "p")
            node.nextSibling();
        console.log(node);
    }
    

    Range

    Range较为专业化,主要是富文本编辑类业务

    var range = new Range(),
        firstText = p.childNodes[1],
        secondText = em.firstChild
    range.setStart(firstText, 9) // do not forget the leading space
    range.setEnd(secondText, 4)
    
    var fragment = range.extractContents()
    range.insertNode(document.createTextNode("aaaa"))
    

    补充算法

    // 深度优先
    function deepLogTagNames(parentNode){
      console.log(parentNode.tagName)
      const childNodes = parentNode.childNodes
      // 过滤没有 tagName 的节点,遍历输出
      Array.prototype.filter.call(childNodes, item=>item.tagName)
      .forEach(itemNode=>{
        deepLogTagNames(itemNode)
      })
    }
    deepLogTagNames(document.body)
    
    // 广度优先
    function breadLogTagNames(root){
      const queue = [root]
      while(queue.length) {
        const currentNode = queue.shift()
        const {childNodes, tagName} = currentNode
        tagName && console.log(currentNode.tagName)
        // 过滤没有 tagName 的节点
        Array.prototype.filter.call(childNodes, item=>item.tagName)
        .forEach(itemNode=>{
          queue.push(itemNode)
        }) 
      }
    }
    breadLogTagNames(document.body)
    

    参考原文: 浏览器DOM:你知道HTML的节点有哪几种吗?

    相关文章

      网友评论

        本文标题:【十七】浏览器DOM:你知道HTML的节点有哪几种吗?

        本文链接:https://www.haomeiwen.com/subject/zldimqtx.html