日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

在浏览器的背后(二) —— HTML语言的语法解析

發布時間:2025/3/14 HTML 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在浏览器的背后(二) —— HTML语言的语法解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

當你看到這篇文章意味著我辜負了@教主的殷切期望周末木有去約會,以及蘇老師@我思故我在北京鼓樓的落井下石成功了……

本文demo powered by 已經結婚的@老趙的不再維護的wind.js

物是人非啊……

?

說回正經事,在上一篇文章中,我們取得了初步成果,毫無意義的字符變成了有意義的token。

接下來我們要把這些簡單的詞變成DOM樹,這個過程我們是使用棧來實現的,任何語言幾乎都有棧,為了給大家跑著玩我們還是用JS來實現吧,JS中的棧只要用數組就好了:

function HTMLSyntaticalParser(){var stack = [new HTMLDocument];this.receiveInput = function(token) {//TODO}this.getOutput = function(){return stack[0];} }

為了構建DOM樹,我們需要一個Node類,接下來我們所有的節點都會是這個Node類的實例。在完全符合標準的瀏覽器中,不一樣的HTML節點對應了不同的Node的子類,我們為了簡化,就不完整實現這個繼承體系了。我們僅僅把Node分為Element和Text(如果是基于類的OOP的話,我們需要抽象工廠來創建對象。)

function Element(){this.childNodes = [];
}
function Text(value){
this.value = value || "";
}

前面我們的token中,以下兩個是需要成對匹配的:

  • tag start
  • tag end

于是我們的做法是遇到tag start就入棧,遇到tag end就出棧,并且校驗一下是否匹配。

對于Text節點,我們則需要把相鄰的Text節點合并起來,我們的做法是當字符token入棧時檢查棧頂是否是Text節點,如果是的話就合并Text節點

同樣我們來看看直觀的解析過程:

<html maaa=a > <head> <title>cool</title> </head> <body> <img src="a" /> </body> </html> parse

當我們的源代碼完全遵循xhtml時,這非常簡單問題,然而HTML具有很強的容錯能力,奧妙在于當tag end跟棧頂的start tag不匹配的時候如何處理。

于是有一個極其復雜的規則來的,幸好w3c又一次很貼心地把全部規則都整理的很好,我們只要翻譯成對應的偽代碼就好了:

http://www.w3.org/html/wg/drafts/html/master/syntax.html#tree-construction

略微干凈的代碼可以在這個gist找到:

https://gist.github.com/wintercn/5618683#file-htmlsyntaticalparser-js

轉載于:https://www.cnblogs.com/winter-cn/p/3141990.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的在浏览器的背后(二) —— HTML语言的语法解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。