这里我们要清楚,我们编写的HTML其实都只是普通的文本,重点在于如何将这种有固定格式的文本渲染到浏览器中,从普通文本到程序的运行必不可少的需要解释和转化(专业点叫词法分析和语法分析)

  • 词法分析:这个过程是对一个个字符读入,并对程序代码进行扫描,根据构词规则识别单词生成token令牌
  • 语法分析:在词法分析的基础上将令牌组合生成各类语法短句,例如表达式、语句等等

举个栗子

HTML文档内容

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <link rel="stylesheet" href="">
  6. </head>
  7. <body>
  8. <p>
  9. Hello
  10. <span>web preformance</span>
  11. students
  12. </p>
  13. <div>
  14. <img src="xxx" alt="xxx">
  15. </div>
  16. </body>
  17. </html>

解析全过程

html-parse.png

  1. 获取HTML文档
    • 浏览器根据URL向服务器发送请求,服务器会将HTML文件的内容放置在响应体中返回给浏览器
    • 确定资源类型:浏览器根据响应头字段content-type得知这是一个HTML文件,准备开始解析HTML文档内容
    • 确定资源编码:浏览器根据响应头字段content-type同时可以确定文件编码,从而正确对文档内容正确转码确保Byte->Charaters的过程
  2. 转码
    • 浏览器使用HTML文档解析工具来逐行读入该文档,然后依次读入Byte字节并转码成Charaters字符,此时才是我们所看到的HTML文档内容
  3. 词法分析

    • 例如浏览器读取到<html>,根据HTML结构规则知道这是一个开始标签,并且标签名叫html;这个解析过程会对文档逐行执行,直到所有的标签都解释完成,存储在一个数组结构tokens中,等待进去下一个流程此流程还不是节点,只是将html文本转换成浏览器能够理解的数据结构
      1. [
      2. // 第1行
      3. { tagName: "html", type: "DOCTYPE", attr: "", text: "" },
      4. { tagName: "", type: "Character", attr: "", text: "\n" },
      5. // 第2行
      6. { tagName: "html", type: "startTag", attr: "", text: "" },
      7. { tagName: "", type: "Character", attr: "", text: "\n " },
      8. // 第3行
      9. { tagName: "head", type: "startTag", attr: "", text: "" },
      10. { tagName: "", type: "Character", attr: "", text: "\n " },
      11. // 第4行
      12. { tagName: "meta", type: "startTag", attr: "charset=UTF-8", text: "" },
      13. { tagName: "meta", type: "endTag", attr: "", text: "" },
      14. { tagName: "", type: "Character", attr: "", text: "\n " },
      15. // 第5行
      16. { tagName: "link", type: "startTag", attr: "rel=stylesheet&href=", text: "" },
      17. { tagName: "link", type: "endTag", attr: "", text: "" },
      18. { tagName: "", type: "Character", attr: "", text: "\n" },
      19. // 第6行
      20. { tagName: "head", type: "endTag", attr: "", text: "" },
      21. { tagName: "", type: "Character", attr: "", text: "\n" },
      22. // 第7行
      23. { tagName: "body", type: "startTag", attr: "", text: "" },
      24. { tagName: "", type: "Character", attr: "", text: "\n " },
      25. // 第8-9行
      26. { tagName: "p", type: "startTag", attr: "", text: "" },
      27. { tagName: "", type: "Character", attr: "", text: "\n Hello\n " },
      28. // 第10-11行
      29. { tagName: "span", type: "startTag", attr: "", text: "" },
      30. { tagName: "", type: "Character", attr: "", text: "web preformance" },
      31. { tagName: "span", type: "endTag", attr: "", text: "" },
      32. { tagName: "", type: "Character", attr: "", text: "\n students\n " },
      33. // 第12行
      34. { tagName: "p", type: "endTag", attr: "", text: "" },
      35. { tagName: "", type: "Character", attr: "", text: "\n " },
      36. // 第13行
      37. { tagName: "div", type: "startTag", attr: "", text: "" },
      38. { tagName: "", type: "Character", attr: "", text: "\n " },
      39. // 第14行
      40. { tagName: "img", type: "startTag", attr: "src=xxx&alt=xxx", text: "" },
      41. { tagName: "img", type: "endTag", attr: "", text: "" },
      42. { tagName: "", type: "Character", attr: "", text: "\n " },
      43. // 第15行
      44. { tagName: "div", type: "endTag", attr: "", text: "" },
      45. { tagName: "", type: "Character", attr: "", text: "\n" },
      46. // 第16行
      47. { tagName: "body", type: "endTag", attr: "", text: "" },
      48. { tagName: "", type: "Character", attr: "", text: "\n" },
      49. // 第17行
      50. { tagName: "html", type: "endTag", attr: "", text: "" },
      51. { tagName: "", type: "Character", attr: "", text: "\n" },
      52. // 第结束
      53. { tagName: "", type: "EndOffile", attr: "", text: "" },
      54. ]
  4. 语法分析

    • 处理通过上一步得到的tokens,将其从数据转换成浏览器内支持并可操作的Node节点
  5. DOM构造
    • 最后根据标签之间的关系,构造成DOM树