重学前端
程劭非(winter)
前手机淘宝前端负责人
立即订阅
32956 人已学习
课程目录
已完结 58 讲
0/4登录后,你可以任选4讲全文学习。
开篇词+学习路线+架构图 (3讲)
开篇词 | 从今天起,重新理解前端
免费
明确你的前端学习路线与方法
列一份前端知识架构图
模块一:JavaScript (15讲)
JavaScript类型:关于类型,有哪些你不知道的细节?
JavaScript对象:面向对象还是基于对象?
JavaScript对象:我们真的需要模拟类吗?
JavaScript对象:你知道全部的对象分类吗?
JavaScript执行(一):Promise里的代码为什么比setTimeout先执行?
JavaScript执行(二):闭包和执行上下文到底是怎么回事?
JavaScript执行(三):你知道现在有多少种函数吗?
JavaScript执行(四):try里面放return,finally还会执行吗?
JavaScript词法:为什么12.toString会报错?
(小实验)理解编译原理:一个四则运算的解释器
JavaScript语法(预备篇):到底要不要写分号呢?
JavaScript语法(一):在script标签写export为什么会抛错?
JavaScript语法(二):你知道哪些JavaScript语句?
JavaScript语法(三):什么是表达式语句?
JavaScript语法(四):新加入的**运算符,哪里有些不一样呢?
模块二:HTML和CSS (16讲)
HTML语义:div和span不是够用了吗?
HTML语义:如何运用语义类标签来呈现Wiki网页?
CSS语法:除了属性和选择器,你还需要知道这些带@的规则
HTML元信息类标签:你知道head里一共能写哪几种标签吗?
CSS 选择器:如何选中svg里的a元素?
CSS选择器:伪元素是怎么回事儿?
HTML链接:除了a标签,还有哪些标签叫链接?
CSS排版:从毕升开始,我们就开始用正常流了
HTML替换型元素:为什么link一个CSS要用href,而引入js要用src呢?
HTML小实验:用代码分析HTML标准
CSS Flex排版:为什么垂直居中这么难?
CSS动画与交互:为什么动画要用贝塞尔曲线这么奇怪的东西?
HTML语言:DTD到底是什么?
CSS渲染:CSS是如何绘制颜色的?
CSS小实验:动手做,用代码挖掘CSS属性
HTML·ARIA:可访问性是只给盲人用的特性么?
模块三:浏览器实现原理与API (9讲)
浏览器:一个浏览器是如何工作的?(阶段一)
浏览器:一个浏览器是如何工作的?(阶段二)
浏览器:一个浏览器是如何工作的(阶段三)
浏览器:一个浏览器是如何工作的?(阶段四)
浏览器:一个浏览器是如何工作的?(阶段五)
浏览器DOM:你知道HTML的节点有哪几种吗?
浏览器CSSOM:如何获取一个元素的准确位置
浏览器事件:为什么会有捕获过程和冒泡过程?
浏览器API(小实验):动手整理全部API
模块四:前端综合应用 (5讲)
性能:前端的性能到底对业务数据有多大的影响?
工具链:什么样的工具链才能提升团队效率?
持续集成:几十个前端一起工作,如何保证工作质量?
搭建系统:大量的低价值需求应该如何应对?
前端架构:前端架构有哪些核心问题?
特别加餐 (9讲)
新年彩蛋 | 2019,有哪些前端技术值得关注?
用户故事 | 那些你与“重学前端”的不解之缘
期中答疑 | name(){}与name: function() {},两种写法有什么区别吗?
答疑加餐 | 学了这么多前端的“小众”知识,到底对我有什么帮助?
加餐 | 前端与图形学
加餐 | 前端交互基础设施的建设
期末答疑(一):前端代码单元测试怎么做?
期末答疑(二):前端架构中,每个逻辑页面如何可以做到独立发布呢?
加餐 | 一个前端工程师到底需要掌握哪些技能?
尾声 (1讲)
尾声 | 长风破浪会有时,直挂云帆济沧海
重学前端
登录|注册

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

winter 2019-03-09
你好,我是 winter。
今天我们进入浏览器 API 的学习, 这一节课,我们来学习一下 DOM API。
DOM API 是最早被设计出来的一批 API,也是用途最广的 API,所以早年的技术社区,常常用 DOM 来泛指浏览器中所有的 API。不过今天这里我们要介绍的 DOM,指的就是狭义的文档对象模型。

DOM API 介绍

首先我们先来讲一讲什么叫做文档对象模型。
顾名思义,文档对象模型是用来描述文档,这里的文档,是特指 HTML 文档(也用于 XML 文档,但是本课不讨论 XML)。同时它又是一个“对象模型”,这意味着它使用的是对象这样的概念来描述 HTML 文档。
说起 HTML 文档,这是大家最熟悉的东西了,我们都知道,HTML 文档是一个由标签嵌套而成的树形结构,因此,DOM 也是使用树形的对象模型来描述一个 HTML 文档。
DOM API 大致会包含 4 个部分。
节点:DOM 树形结构中的节点相关 API。
事件:触发和监听事件相关 API。
Range:操作文字范围相关 API。
遍历:遍历 DOM 需要的 API。
事件相关 API 和事件模型,我们会用单独的课程讲解,所以我们本篇文章重点会为你介绍节点和遍历相关 API。
DOM API 数量很多,我希望给你提供一个理解 DOM API 设计的思路,避免单靠机械的方式去死记硬背。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《重学前端》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(20)

  • 周序猿
    // 深度优先
    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)
    2019-03-10
    24
  • 阿成
    第一段代码中的 DocumentFragment 应该改为 DocumentType...

    /**
     * @param {Element} el
     * @param {(Element) => void} action
    function walk (el, action) {
      if (el) {
        action(el)
        walk(el.firstElementChild, action)
        walk(el.nextElementSibling, action)
      }
    }

    walk(document.documentElement, el => console.log(el.nodeName))

    // 如果想要去重...
    const set = new Set()
    walk(document.documentElement, el => {
      set.add(el.nodeName)
    })
    for (let n of set)
      console.log(n)
    2019-03-09
    12
  • 天亮了
    这样可以把tagName全打印出来...
    document.getElementsByTagName('*');
    2019-05-06
    2
    7
  • kino
    insertBefore(newNode,null)和appendChild的区别是啥
    2019-03-12
    3
  • 我叫张小咩²⁰¹⁹
    var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, false)
    var node
    while(node = walker.nextNode())
        console.log(node.tagName)
    ---------- or recursive ------------

    const result = []
    function getAllTagName(parent) {
    const childs = Array.from(parent.children)
    result.push(...childs.map(el => el.tagName))
    for (var i = 0; i < childs.length; i++) {
    if (childs[i].children.length) getAllTagName(childs[i])
    }

    if (i == 0) return
    }
    getAllTagName(document)

    console.log(result)


    2019-03-10
    3
  • ttys000
    document.querySelectorAll('*'),这样有点过分了
    2019-06-17
    1
  • 小二子大人
    const root = document.getElementsByTagName('html')[0];
        // 深度优先遍历
        function deepLogTagName(root) {
            console.log(root.tagName);
            if (root.childNodes.length > 0) {
                for (let i = 0; i < root.childNodes.length; i++) {
                    if (root.childNodes[i].nodeType === 1) {
                        deepLogTagName(root.childNodes[i]);
                    }
                }
            }
        }
        deepLogTagName(root);
        console.log("111111111111111111111")

        // 广度优先遍历
        console.log(root.tagName);
        function breadLogTagName(root) {
            if (root.childNodes.length > 0) {
                for (let i = 0; i < root.childNodes.length; i++) {
                    if (root.childNodes[i].nodeType === 1) {
                        console.log(root.childNodes[i].tagName);
                    }
                }
                for (let i = 0; i < root.childNodes.length; i++) {
                    if (root.childNodes[i].nodeType === 1) {
                        breadLogTagName(root.childNodes[i]);
                    }
                }
            }
        }
        breadLogTagName(root)
    2019-05-08
    1
  • 腾松
    function loop(node){
    if(!node){
    return
    }
    if(node.nodeType === document.ELEMENT_NODE)
    console.log(node.nodeName);
    if(node.childNodes){
    node.childNodes.forEach(child => {
    loop(child)
    })
    }
    }
    loop(document)
    2019-03-26
    1
  • 宇宙全栈
    第一段代码中的 DocumentFragment 应该改为 DocumentType
    2019-03-11
    1
  • 莫非
    引用:如果你追求极致的性能,还可以把 Attribute 当作节点:getAttributeNode,setAttributeNode。
    2019-10-18
  • 大力
    let set = new Set();
    Array.from(document.getElementsByTagName('*')).map(node => set.add(node.tagName.toLowerCase()));
    let list = Array.from(set).sort();
    console.log(list);
    2019-10-11
  • kgdmhny
    老师,请问一下,"对 DOM 而言,Attribute 和 Property 是完全不同的含义,只有特性场景下,两者才会互相关联(这里在后面我会详细讲解,今天的文章里我就不展开了)"后面有讲解这块吗?

    作者回复: 有啊

    2019-06-05
  • 胡琦
    膜拜前排各位大佬,学习了!
    2019-05-06
  • Sticker
    void function loop(parent){
        const children = parent.childNodes;
        children.forEach(item => {
            if(item.nodeType === 1){
                console.log(item.nodeName)
                if(item.childNodes.length > 0){
                    loop(item)
                }
            }
        })
    }(document);
    2019-04-25
  • Ramda
    const $body = document.body
        
            function deep (parentNode) {
                const children = parentNode.childNodes
                children.forEach(item => {
                    if(item.nodeType === 1 ) {
                        console.log(item.nodeName)
                        if (item.childNodes.length > 0) {
                            deep(item)
                        }
                    }
                })
            }
            deep($body)
    2019-04-19
  • 踏凌霄
    void function queryAndPrintSon(params) {
          var child = params.children
          for (let index = 0; index < child.length; index++) {
            const element = child[index];
            console.log(element.tagName)
            queryAndPrintSon(element)
          }
        }(document.getRootNode())
    2019-04-17
  • 周飞
    let tagNameArr = [];
        function travaldom(root){
          if(root.tagName && root.tagName !=='text') tagNameArr.push(root.tagName)
           root.childNodes.forEach(node=>{
              travaldom(node);
           });
        }
        travaldom(document);
        console.log(tagNameArr)
    2019-03-27
  • 逐梦无惧
    老师请问这些html的结构化内容有在哪本书进行介绍吗
    2019-03-27
  • 花骨朵
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>遍历输出tagName</title>
    </head>
    <body>
      <section>
        <header>This is a header</header>
        <div>
          <h4>This is a content title</h4>
          <p>This is the <em>first</em> paragraph.</p>
          <p>This is the <strong>second</strong> paragraph.</p>
        </div>
        <footer>This is a footer of this page.</footer>
      </section>
      <script>
        const secElement = document.getElementById('sec');
        function getChildTagNames() {
          const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, null, false)
          let node;
          while(node = walker.nextNode()) {
            if(node.tagName)
            console.log(node.tagName);
          }
        }
        getChildTagNames(secElement);
      </script>
    </body>
    </html>
    2019-03-22
  • Ppei
    老师:
    比如 document.body.attribute.class = “a” 等效于 document.setAttribute(“class”, “a”)。
    应该是 document.body.attributes吧?
    疑惑:
    var divDom = document.createElement('div')
    divDom.attributes.id = 'app'
    divDom.setAttribute('class', 'app')
    为什么在divDom上看不到id属性?append到页面中后,同样用getElementById也选择不到这个DOM,用class就可以。
    2019-03-11
收起评论
20
返回
顶部