整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          你不可不知的HTML優(yōu)化技巧,還不抓緊時(shí)間收藏

          何提升Web頁(yè)面的性能,很多開(kāi)發(fā)人員從多個(gè)方面來(lái)下手如JavaScript、圖像優(yōu)化、服務(wù)器配置,文件壓縮或是調(diào)整CSS。

          很顯然HTML 已經(jīng)達(dá)到了一個(gè)瓶頸,盡管它是開(kāi)發(fā)Web 界面必備的核心語(yǔ)言。HTML頁(yè)面的負(fù)載也是越來(lái)越重。大多數(shù)頁(yè)面平均需要40K的空間,像一些大型網(wǎng)站會(huì)包含數(shù)以千計(jì)的HTML 元素,頁(yè)面Size會(huì)更大。

          如何有效的降低HTML 代碼的復(fù)雜度和頁(yè)面元素的數(shù)量,本文主要解決了這個(gè)問(wèn)題,從多個(gè)方面介紹了如何編寫(xiě)簡(jiǎn)練,清晰的HTML 代碼,能夠使得頁(yè)面加載更為迅速,且能在多種設(shè)備中運(yùn)行良好。

          在設(shè)計(jì)和開(kāi)發(fā)過(guò)程中需要遵循以下原則:

          • 結(jié)構(gòu)分離:使用HTML 增加結(jié)構(gòu),而不是樣式內(nèi)容;
          • 保持整潔:為工作流添加代碼驗(yàn)證工具;使用工具或樣式向?qū)ЬS護(hù)代碼結(jié)構(gòu)和格式
          • 學(xué)習(xí)新語(yǔ)言:獲取元素結(jié)構(gòu)和語(yǔ)義標(biāo)記。
          • 確保可訪問(wèn): 使用ARIA 屬性和Fallback 屬性等
          • 測(cè)試: 使網(wǎng)站在多種設(shè)備中能夠良好運(yùn)行,可使用emulators和性能工具。

          HTML,CSS 和JavaScript三者的關(guān)系

          HTML 是用于調(diào)整頁(yè)面結(jié)構(gòu)和內(nèi)容的標(biāo)記語(yǔ)言。HTML 不能用于修飾樣式內(nèi)容,也不能在頭標(biāo)簽中輸入文本內(nèi)容,使代碼變得冗長(zhǎng)和復(fù)雜,相反使用CSS 來(lái)修飾布局元素和外觀比較合適。HTML元素默認(rèn)的外觀是由瀏覽器默認(rèn)的樣式表定義的,如在Chrome中h1標(biāo)簽元素會(huì)渲染成32px的Times 粗體。

          三條通用設(shè)計(jì)規(guī)則:

          1. 使用HTML 來(lái)構(gòu)造頁(yè)面結(jié)構(gòu),CSS修飾頁(yè)面呈現(xiàn),JavaScript實(shí)現(xiàn)頁(yè)面功能。CSS ZenGarden 很好地展示了行為分離。
          2. 如果能用CSS或JavaScript實(shí)現(xiàn)就少用HTML代碼。
          3. 將CSS和JavaScript文件與HTML 分開(kāi)存放。這可有助于緩存和調(diào)試。

          文檔結(jié)構(gòu)方面也可以做優(yōu)化,如下:

          • 使用HTML5 文檔類型,以下是空文件:
          <!DOCTYPE html>
          <html>
          <head>
           <title>Recipes: pesto</title>
          </head>
          <body>
           <h1>Pesto</h1>
           <p>Pesto is good!</p>
          </body>
          </html>
          
          • 在文檔起始位置引用CSS文件,如下:
          <head>
           <title>My pesto recipe</title>
           <link rel="stylesheet" href="/css/global.css">
           <link rel="stylesheet" href="css/local.css">
          </head>
          

          使用這兩種方法,瀏覽器會(huì)在解析HTML代碼之前將CSS信息準(zhǔn)備好。因此有助于提升頁(yè)面加載性能。

          在頁(yè)面底部body結(jié)束標(biāo)簽之前輸入JavaScript代碼,這樣有助于提升頁(yè)面加載的速度,因?yàn)闉g覽器在解析JavaScript代碼之前將頁(yè)面加載完成,使用JavaScript會(huì)對(duì)頁(yè)面元素產(chǎn)生積極的影響。

          <body>
           ...
           <script src="/js/global.js">
           <script src="js/local.js">
          </body>
          

          使用Defer和async屬性,腳本元素具有async 屬性無(wú)法保證會(huì)按順序執(zhí)行。

          可在JavaScript代碼中添加Handlers。千萬(wàn)別加到HTML內(nèi)聯(lián)代碼中,比如下面的代碼則容易導(dǎo)致錯(cuò)誤且不易于維護(hù):

          index.html:

          <head>
           ...
           <script src="js/local.js">
          </head>
          <body onload="init()">
           ...
           <button onclick="handleFoo()">Foo</button>
           ...
          </body>
          

          下面的寫(xiě)法比較好:

          index.html:

          <head>
           ...
          </head>
          <body>
           ...
           <button id="foo">Foo</button>
           ...
           <script src="js/local.js">
          </body>
          

          js/local.js:

          init();
          var fooButton =
           document.querySelector('#foo');
          fooButton.onclick = handleFoo();
          

          驗(yàn)證

          優(yōu)化網(wǎng)頁(yè)的一種方法就是瀏覽器可處理非法的HTML 代碼。合法的HTML代碼很容易調(diào)試,且占內(nèi)存少,耗費(fèi)資源少,易于解析和渲染運(yùn)行起來(lái)更快。非法的HTML代碼讓實(shí)現(xiàn)響應(yīng)式設(shè)計(jì)變得異常艱難。

          當(dāng)使用模板時(shí),合法的HTML代碼顯得異常重要,經(jīng)常會(huì)發(fā)生模板單獨(dú)運(yùn)行良好,當(dāng)與其他模塊集成時(shí)就報(bào)各種各樣的錯(cuò)誤,因此一定要保證HTML代碼的質(zhì)量,可采取以下措施:

          • 在工作流中添加驗(yàn)證功能:使用驗(yàn)證插件如HTMLHint或SublineLinter幫助你檢測(cè)代碼錯(cuò)誤。
          • 使用HTML5文檔類型
          • 確保HTML的層次結(jié)構(gòu)易于維護(hù),要避免元素嵌套處于左開(kāi)狀態(tài)。
          • 保證添加各元素的結(jié)束標(biāo)簽。
          • 刪除不必要的代碼 ;沒(méi)有必要為自關(guān)閉的元素添加結(jié)束標(biāo)簽;Boolean 屬性不需要賦值,如果存在則為True;

          代碼格式

          格式一致性使得HTML代碼易于閱讀,理解,優(yōu)化,調(diào)試。

          語(yǔ)義標(biāo)記

          語(yǔ)義指意義相關(guān)的事物,HTML 可從頁(yè)面內(nèi)容中看出語(yǔ)義:元素和屬性的命名一定程度上表達(dá)了內(nèi)容的角色和功能。HTML5 引入了新的語(yǔ)義元素,如<header>,<footer>及<nav>。

          選擇合適的元素來(lái)編寫(xiě)代碼可保證代碼的易讀性:

          • 使用<h1>(<h2>,<h3>…)表示標(biāo)題,<ul>或<ol>實(shí)現(xiàn)列表
          • 注意使用<article> 標(biāo)簽之前應(yīng)添加<h1>標(biāo)簽;
          • 選擇合適的HTML5語(yǔ)義元素如<header>,<footer>,<nav>,<aside>;
          • 使用<p>描述Body 文本,HTML5 語(yǔ)義元素可以形成內(nèi)容,反之不成立。
          • 使用<em>和<strong>標(biāo)簽替代<i>和<b>標(biāo)簽。
          • 使用<label>元素,輸入類型,占位符及其他屬性來(lái)強(qiáng)制驗(yàn)證。
          • 將文本和元素混合,并作為另一元素的子元素,會(huì)導(dǎo)致布局錯(cuò)誤,

          例如:

          <div>Name: <input type="text" id="name"></div>
          

          換種寫(xiě)法會(huì)更好:

           1: <div>
           2: <label for="name">Name:</label><input type="text" id="name">
           3: </div>
          

          布局

          要提高HTML代碼的性能,要遵循HTML 代碼以實(shí)現(xiàn)功能和為目標(biāo),而不是樣式。

          • 使用<p>元素修飾文本,而不是布局;默認(rèn)<p>是自動(dòng)提供邊緣,而且其他樣式也是瀏覽器默認(rèn)提供的。
          • 避免使用<br>分行,可以使用block元素或CSS顯示屬性來(lái)代替。
          • 避免使用<hr>來(lái)添加水平線,可使用CSS的border-bottom 來(lái)代替。
          • 不到關(guān)鍵時(shí)刻不要使用div標(biāo)簽。
          • 盡量少用Tables來(lái)布局。
          • 可以多使用Flex Box
          • 使用CSS 來(lái)調(diào)整邊距等。

          CSS

          雖然本文講解的是如何優(yōu)化HTML,下面介紹了一些使用css的基本技能:

          • 避免內(nèi)聯(lián)css
          • 最多使用ID類 一次
          • 當(dāng)涉及多個(gè)元素時(shí),可使用Class來(lái)實(shí)現(xiàn)。

          以上就是本文介紹的優(yōu)化HTML代碼的技巧,一個(gè)高質(zhì)量高性能的網(wǎng)站,往往取決于對(duì)細(xì)節(jié)的處理,因此我們?cè)谌粘i_(kāi)發(fā)中,能夠考慮到用戶體驗(yàn),后期維護(hù)等方面,則會(huì)產(chǎn)生更高效的開(kāi)發(fā)。

          在學(xué)習(xí)和工作中,我們經(jīng)常需要使用日志來(lái)記錄程序的運(yùn)行狀態(tài)和調(diào)試信息。而為了更好地區(qū)分不同的日志等級(jí),我們可以使用不同的顏色來(lái)呈現(xiàn),使其更加醒目和易于閱讀。

          在下圖運(yùn)行結(jié)果中,我們使用了 colorlog 庫(kù)來(lái)實(shí)現(xiàn)彩色日志輸出。通過(guò)定義不同日志等級(jí)對(duì)應(yīng)的顏色,我們可以在控制臺(tái)中以彩色的方式顯示日志信息。例如,DEBUG 級(jí)別的日志使用白色,INFO 級(jí)別的日志使用綠色,WARNING 級(jí)別的日志使用黃色,ERROR 級(jí)別的日志使用紅色,CRITICAL 級(jí)別的日志使用藍(lán)色。

          但是在查看日志文件時(shí),我們會(huì)發(fā)現(xiàn)日志信息是系統(tǒng)默認(rèn)的字體顏色,并且前后多了一些特殊符號(hào),例如 [32m 等。這是因?yàn)樵诳刂婆_(tái)中使用的是 ANSI 轉(zhuǎn)義序列來(lái)實(shí)現(xiàn)彩色文本效果,而這些特殊符號(hào)是 ANSI 轉(zhuǎn)義序列的一部分。如下圖所示:

          現(xiàn)在有一個(gè)需求,在前端頁(yè)面直接查看日志內(nèi)容并還原彩色文本效果,因此,我們將進(jìn)行以下內(nèi)容講解:

          1. 什么是 ANSI 轉(zhuǎn)義序列?
          2. 如何在前端頁(yè)面直接查看日志內(nèi)容?
          3. 如何在前端頁(yè)面還原彩色文本效果?

          本文代碼點(diǎn)擊此處跳轉(zhuǎn),往期系列文章請(qǐng)?jiān)L問(wèn)博主的 項(xiàng)目實(shí)戰(zhàn)專欄,博文中的所有代碼全部收集在博主的 GitHub 倉(cāng)庫(kù)中;

          ANSI 轉(zhuǎn)義序列

          ANSI 轉(zhuǎn)義序列是美國(guó)國(guó)家標(biāo)準(zhǔn)化組織(American National Standards Institute,ANSI)制定的標(biāo)準(zhǔn),是一種用于控制文本終端顯示的特殊字符序列。它們以 3[ 開(kāi)頭,以字母和數(shù)字組合的形式表示不同的控制功能。

          ANSI 轉(zhuǎn)義序列可以用于控制文本的顏色、背景色、文本樣式(如粗體、斜體等)、光標(biāo)位置、清屏等操作。通過(guò)在輸出文本中插入適當(dāng)?shù)?ANSI 轉(zhuǎn)義序列,可以實(shí)現(xiàn)豐富的終端顯示效果。

          以下是一些常用的 ANSI 轉(zhuǎn)義序列示例:

          • 3[0m:重置所有屬性,恢復(fù)默認(rèn)設(shè)置;
          • 3[31m:設(shè)置文本顏色為紅色;
          • 3[42m:設(shè)置背景顏色為綠色;
          • 3[1m:設(shè)置文本為粗體;
          • 3[4m:設(shè)置文本為下劃線;
          • 3[2J:清屏;

          需要注意的是,ANSI 轉(zhuǎn)義序列在不同的終端和操作系統(tǒng)上的支持程度可能會(huì)有所不同。在某些終端中,可能無(wú)法正確解釋和顯示 ANSI 轉(zhuǎn)義序列。

          我們以 3[31m 和 3[42m 為例,輸出一個(gè)綠底紅字的句子 Hello World! --sidiot.,代碼如下所示:

          log.debug("3[42m3[31mHello World! --sidiot.3[0m3[0m")

          運(yùn)行結(jié)果:

          前端頁(yè)面直接查看日志內(nèi)容

          這里的話,我們使用 Python 的 http.server 模塊來(lái)啟動(dòng)一個(gè)簡(jiǎn)單的 HTTP 服務(wù)器。

          比較快捷的方式就是在日志文件夾中打開(kāi)終端,輸入 python -m http.server 8888 即可,運(yùn)行結(jié)果如下所示:

          不過(guò)這種方式相對(duì)來(lái)說(shuō)還是不太安全的,因此我們可以通過(guò)設(shè)置白名單的方式,來(lái)規(guī)避一些潛在的安全隱患,代碼如下所示:

          import http.server
          import socketserver
          
          class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
              def check_client_address(self):
                  # 設(shè)置白名單,只允許特定的IP地址或主機(jī)訪問(wèn)
                  whitelist = ['127.0.0.1', 'localhost']
          
                  client_address = self.client_address[0]
                  if client_address not in whitelist:
                      self.send_response(403)
                      self.end_headers()
                      self.wfile.write(b'Forbidden. Please contact sidiot.')
                      return False
          
                  return True
          
              def do_GET(self):
                  if not self.check_client_address():
                      return
                  
                  super().do_GET()
          
          with socketserver.TCPServer(('0.0.0.0', 8888), HTTPRequestHandler) as httpd:
              httpd.serve_forever()

          目前本機(jī)的 IP 為 192.168.124.23,當(dāng)我們以 127.0.0.1 來(lái)訪問(wèn) 8888 服務(wù)端口時(shí),訪問(wèn)是成功的,但是當(dāng)我們用 192.168.124.23 來(lái)訪問(wèn)服務(wù)端口時(shí),訪問(wèn)是失敗的。

          運(yùn)行結(jié)果:

          現(xiàn)在我們點(diǎn)擊文件,它會(huì)直接通過(guò)瀏覽器直接下載,但是我們需要的是在網(wǎng)頁(yè)上能夠直接閱覽文件中的內(nèi)容,因此我們可以從 do_GET() 下手。

          我們可以設(shè)計(jì)一個(gè)根據(jù)傳入的文件名參數(shù),讀取本地文件并作為響應(yīng)結(jié)果進(jìn)行返回的方法,然后根據(jù)一定的規(guī)則進(jìn)行觸發(fā),代碼如下所示:

          def read_file(self):
              try:
                  self.send_response(200)
                  self.send_header("Content-Type", "text/plain; charset=utf-8")
                  self.end_headers()
                  self.wfile.write(open(self.path[6:], 'rb').read())
          
              except FileNotFoundError:
                  self.send_response(404)
                  self.end_headers()
                  self.wfile.write(b'File not found!')
          
          def do_GET(self):
              if self.check_client_address():
                  if self.path.startswith("/?log="):
                      self.read_file()
                  else:
                      super().do_GET()

          上述代碼通過(guò)檢查請(qǐng)求的資源路徑來(lái)處理 GET 請(qǐng)求。如果請(qǐng)求的資源路徑前綴是 /?log=,且是當(dāng)前目錄下存在的日志文件,它會(huì)讀取文件并將其內(nèi)容作為響應(yīng)發(fā)送。否則,它會(huì)使用基類的默認(rèn)行為處理普通的 GET 請(qǐng)求。

          運(yùn)行結(jié)果:

          至此,我們已經(jīng)實(shí)現(xiàn)了前端頁(yè)面直接查看日志內(nèi)容的功能。

          前端頁(yè)面還原彩色文本效果

          原理分析

          當(dāng)我們想要在前端頁(yè)面展示 ANSI 字體的彩色效果時(shí),我們只需要簡(jiǎn)單地將 ANSI 轉(zhuǎn)義序列轉(zhuǎn)換成相應(yīng)的 HTML 代碼就可以實(shí)現(xiàn)了。這個(gè)轉(zhuǎn)換過(guò)程實(shí)際上可以通過(guò)編寫(xiě)一個(gè) Python 函數(shù)來(lái)實(shí)現(xiàn),該函數(shù)可以接受包含 ANSI 控制碼的字符串作為輸入,并將其轉(zhuǎn)換為帶有相應(yīng)樣式的 HTML 代碼輸出,代碼如下所示:

          def convert_ansi_to_html(ansi_text):
              ansi_to_html = {
                  '\x1b[31m': '<span style="color: red;">',
                  '\x1b[42m': '<span style="background-color: green;">',
                  ...,
              }
              html_text = re.sub(r'\x1b[[0-9;]*m', lambda match: ansi_to_html.get(match.group(0), ''), ansi_text)
          
              return html_text
          
          
          if __name__ == '__main__':
              ansi = "\033[42m\033[31mHello World! --sidiot.\033[0m\033[0m"
              print(ansi)
              html = convert_ansi_to_html(ansi)
              print(f"convert content: {html}")

          需要注意的是,在 ANSI 轉(zhuǎn)義序列中,\x1b 和 3 都代 表ASCII 碼中的 Escape 字符,用于開(kāi)始一個(gè)轉(zhuǎn)義序列。

          運(yùn)行結(jié)果:

          使用 ansiconv 轉(zhuǎn)換

          接下來(lái),我們借助已有的庫(kù)函數(shù) ansiconv 進(jìn)行 ANSI 的轉(zhuǎn)換。

          通過(guò) pip 進(jìn)行安裝:

          pip install ansiconv

          根據(jù) ansiconv 的官方文檔使用其中的三個(gè)方法 to_plain(),to_html() 和 base_css() 來(lái)實(shí)現(xiàn)在前端頁(yè)面展示 ANSI 字體的彩色效果,代碼如下所示:

          import ansiconv
          
          ansi = "\033[42m\033[31mHello World! --sidiot.\033[0m\033[0m"
          print(f"Ansi: {ansi}")
          plain = ansiconv.to_plain(ansi)
          html = ansiconv.to_html(ansi)
          print(f"Convert Plain: {plain}")
          print(f"Convert HTML: {html}")

          在 base_css() 中會(huì)有相關(guān)的 CSS 映射表,如下所示:

          css_rule('.ansi31', color="#FF0000"),
          css_rule('.ansi42', background_color="#00FF00"),

          運(yùn)行結(jié)果:

          研究 ansiconv 源碼

          我們將通過(guò)研究 ansiconv 的源碼,以便深入了解它是如何將 ANSI 轉(zhuǎn)換成純文本或 HTML 代碼的工作原理。

          to_plain() 的源碼如下所示:

          上述代碼使用正則表達(dá)式匹配字符串中的 ANSI 轉(zhuǎn)義序列,并將其替換為空字符串,從而得到不包含轉(zhuǎn)義序列的純文本。

          正則表達(dá)式的含義如下:

          • \x1B:匹配 ESCAPE 字符;
          • \[:匹配左方括號(hào);
          • [0-9;]*:匹配零個(gè)或多個(gè)數(shù)字或分號(hào);
          • [ABCDEFGHJKSTfmnsulh]:匹配 ANSI 轉(zhuǎn)義序列中的控制字符;

          我們通過(guò) re.findall() 方法來(lái)獲取所有匹配的結(jié)果,這樣夠清晰地捕獲所有符合條件的匹配項(xiàng),從而更好地理解 ansiconv 是如何進(jìn)行 ANSI 到純文本的轉(zhuǎn)換,代碼如下所示:

          ansi = "\033[42m\033[31mHello World! --sidiot.\033[0m\033[0m"
          print(re.findall(r'\x1B[[0-9;]*[ABCDEFGHJKSTfmnsulh]', ansi))

          運(yùn)行結(jié)果:


          to_html() 的源碼如下所示:

          上述代碼將 ANSI 字符串分割成塊,并對(duì)每個(gè)塊調(diào)用 _block_to_html() 函數(shù)進(jìn)行解析和轉(zhuǎn)換,同時(shí)還處理了 ANSI 命令 "A",模擬向上移動(dòng)光標(biāo)的行為。如果 replace_newline 為 True,則 HTML 字符串中的換行符 \n 將替換為 <br />\n 以保留 HTML 輸出中的換行符。

          其中 _block_to_html() 的源碼如下所示:

          上述代碼使用正則表達(dá)式匹配 ANSI 代碼,并根據(jù)匹配結(jié)果生成對(duì)應(yīng)的 HTML 代碼。

          正則表達(dá)式的含義:

          • ^:表示匹配字符串的開(kāi)頭。
          • \[:匹配左方括號(hào) [。
          • (?P<code>\d+(?:;\d+)*)?:這是一個(gè)命名捕獲組,用于匹配 ANSI 代碼中的數(shù)字部分。它由以下組成: \d+:匹配一個(gè)或多個(gè)數(shù)字。 (?:;\d+)*:這是一個(gè)非捕獲組,用于匹配分號(hào) ; 和一個(gè)或多個(gè)數(shù)字的重復(fù)出現(xiàn)。(?: ... ) 表示非捕獲組,* 表示重復(fù)零次或多次。
          • (?P<command>[Am]):這是另一個(gè)命名捕獲組,用于匹配 ANSI 代碼中的命令部分。它由以下組成: [Am]:匹配字符 A 或 m。

          我們可以通過(guò)運(yùn)行源碼里的部分代碼來(lái)幫助理解,代碼如下所示:

          text = ("\x1B[0;32;45msidiot\n"
                  "\033[42m\033[31mHello World! --sidiot.\033[0m\033[0m")
          print(text)
          blocks = text.split('\x1B')
          print(blocks)
          for block in blocks:
              match = re.match(r'^[(?P<code>\d+(?:;\d+)*)?(?P<command>[Am])', block)
              if match is not None:
                  print("\nmatch:", match, ", code:", match.group('code'), ", command:", match.group('command'))

          運(yùn)行結(jié)果:

          實(shí)際應(yīng)用

          通過(guò)深入理解 ANSI 轉(zhuǎn)換思路和 ansiconv 源碼,我們可以為之前的 http.server 服務(wù)帶來(lái)全新的優(yōu)化。

          首先,將原先的 read_file() 方法進(jìn)行優(yōu)化,代碼如下所示:

          def read_file(self, content_type, file_io):
              try:
                  self.send_response(200)
                  self.send_header("Content-Type", f"{content_type}; charset=utf-8")
                  self.end_headers()
                  self.wfile.write(file_io)
          
              except FileNotFoundError:
                  self.send_response(404)
                  self.send_header("Content-Type", "text/plain; charset=utf-8")
                  self.end_headers()
                  self.wfile.write(b'File not found!')

          上述代碼通過(guò)接收 content_type 和 file_io 兩個(gè)參數(shù),實(shí)現(xiàn)將自定義內(nèi)容作為響應(yīng)返回給客戶端。

          然后修改請(qǐng)求路徑,使其能夠返回純文本HTML 兩種不同類型的內(nèi)容,代碼如下所示:

          def do_GET(self):
              if self.check_client_address():
                  if self.path.startswith("/?plain="):
                      file = open(self.path[8:], 'rb').read()
                      plain = ansiconv.to_plain(file.decode('UTF-8'))
                      self.read_file("text/plain", plain.encode())
                  elif self.path.startswith("/?html="):
                      file = open(self.path[7:], 'rb').read()
                      conv = ansiconv.to_html(file.decode('UTF-8'))
                      css = ansiconv.base_css()
                      html = """
                      <html>
                        <head><style>{0}</style></head>
                        <body>
                          <pre class="ansi_fore ansi_back">{1}</pre>
                        </body>
                      </html>
                      """.format(css, conv)
                      print(html)
                      self.read_file("text/html", html.encode())
                  else:
                      super().do_GET()

          這里要注意的是,需要設(shè)置 CSS 樣式,不然 class 類是無(wú)法進(jìn)行渲染的。

          純文本運(yùn)行結(jié)果:

          HTML 運(yùn)行結(jié)果:

          后記

          在本文中,我們探討了如何實(shí)現(xiàn)將 ANSI 字體在前端頁(yè)面進(jìn)行彩色展示的方法。在前端頁(yè)面中直接顯示 ANSI 轉(zhuǎn)義序列是不起作用的,因?yàn)闉g覽器不會(huì)解析和處理這些轉(zhuǎn)義序列。

          為了在前端頁(yè)面實(shí)現(xiàn)彩色展示,我們介紹了一種方法,即將 ANSI 轉(zhuǎn)義序列轉(zhuǎn)換為對(duì)應(yīng)的 HTML 代碼。通過(guò)解析 ANSI 轉(zhuǎn)義序列并將其轉(zhuǎn)換為適當(dāng)?shù)?HTML 標(biāo)簽和樣式,我們可以在前端頁(yè)面上還原彩色文本的效果。

          在本文中,我們使用了 Python 中的 ansiconv 庫(kù)來(lái)實(shí)現(xiàn) ANSI 轉(zhuǎn)換。該庫(kù)提供了 to_plain 和 to_html 兩個(gè)方法,分別用于將 ANSI 轉(zhuǎn)義序列轉(zhuǎn)換為純文本和 HTML 代碼。我們還展示了如何使用這些方法來(lái)轉(zhuǎn)換 ANSI 字符串,并在前端頁(yè)面上顯示轉(zhuǎn)換后的結(jié)果。

          通過(guò)本文的介紹,讀者可以了解到如何在前端頁(yè)面實(shí)現(xiàn)彩色文本的展示,從而提升用戶體驗(yàn)和可讀性。無(wú)論是在日志查看器、終端模擬器還是其他需要展示彩色文本的應(yīng)用中,這種技術(shù)都能發(fā)揮重要作用。

          以上就是 從終端到瀏覽器:實(shí)現(xiàn) ANSI 字體在前端頁(yè)面的彩色展示 的所有內(nèi)容了,希望本篇博文對(duì)大家有所幫助!歡迎大家持續(xù)關(guān)注我的博客,一起分享學(xué)習(xí)和成長(zhǎng)的樂(lè)趣!?

          作者:sidiot
          鏈接:https://juejin.cn/post/7381820436274184202

          html圖像

          在htmtl中,圖像由<img>標(biāo)簽定義.<img>是空標(biāo)簽,它只包含屬性,并且沒(méi)有閉合標(biāo)簽.

          要在頁(yè)面上顯示圖像,使用源屬性(src).源屬性的值是圖像的url地址(統(tǒng)一資源定位符).

          定義圖像的語(yǔ)法是:

          <img src="url"/>

          url指存儲(chǔ)圖像的位置.

          <html>

          <head>

          <title>first page</title>

          </head>

          <body>

          <img src="logo.png" alt=" "/>

          </body>

          <html>

          ●如果圖像無(wú)法顯示,則alt屬性用來(lái)為圖像定義一串預(yù)備的可替換的文本.alt屬性是必需的.

          height(高度)與width(高度)屬性用于設(shè)置圖像的高度與寬度.該屬性值可以以像素百分比形式指定,默認(rèn)單位為像素

          <html>

          <head>

          <title>first page</title>

          </head>

          <body>

          <img src="logo.png" height="100px" width="100px" alt=" "/>

          <!--或者-->

          <img src="logo.png" height="80%" width="80%" alt=" "/>

          </body>

          </html>

          ●<img>的border屬性規(guī)定圖像周圍的邊框的寬度.默認(rèn)情況下,圖像是沒(méi)有邊框的

          border屬性的屬性值的單位是像素.表示邊框的寬度

          實(shí)例:帶有2個(gè)像素粗邊框的圖像.

          <img src="logo.png" height="100px" width="100px" border="2" alt=" " />

          二 html鏈接

          html使用標(biāo)簽<a>來(lái)設(shè)置超文本鏈接.

          超鏈接可以是一個(gè)字,一個(gè)詞,或者一組詞,也可以是一幅圖像,你可以點(diǎn)擊這些內(nèi)容來(lái)跳轉(zhuǎn)到新的文檔或者當(dāng)前文檔中的某個(gè)部分.

          在標(biāo)簽<a>中,使用href(hyper text reference)屬性來(lái)描述鏈接的目標(biāo)地址

          鏈接的html代碼很簡(jiǎn)單.格式如下:

          <a href="url">鏈接文本</a>

          上邊的代碼顯示為:鏈接文本(鏈接文本下面有下劃線)

          ●使用target屬性,你可以規(guī)定在何處打開(kāi)鏈接文檔.如果給target屬性賦值_blank,將使鏈接在新窗口或新選項(xiàng)卡中打開(kāi).

          <a href="url" target="_blank">鏈接文本</a>

          三 html列表

          無(wú)序列表是一個(gè)項(xiàng)目的列表,此列項(xiàng)目使用粗體圓點(diǎn)(典型的小黑圓圈)進(jìn)行標(biāo)記

          無(wú)序列表使用<ul>標(biāo)簽,與<li>標(biāo)簽一起使用(unordered list)

          <ul>

          <li>咖啡</li>

          <li>茶</li>

          <li>牛奶</li>

          </ul>

          瀏覽器顯示效果如下:

          有序列表也是一列項(xiàng)目,列表項(xiàng)目使用數(shù)字進(jìn)行標(biāo)記.

          有序列表始于<ol>標(biāo)簽,每個(gè)列表項(xiàng)目始于<li>標(biāo)簽.

          <ol>

          <li>咖啡</li>

          <li>菜</li>

          <li>牛奶</li>

          </ol>

          運(yùn)行效果如下:

          四 html表格

          表格由<table>標(biāo)簽定義.

          每個(gè)表格均有若干行(由<tr>標(biāo)簽定義,table row),每行被分割為若干單元格(由<td>標(biāo)簽定義,table division)

          下面是一個(gè)包含兩行兩列的表格:

          <table border="2">

          <tr>

          <td>阿/td>

          <td>平</td>

          </tr>

          <tr>

          <td>加</td>

          <td>油</td>

          </tr>

          </table>

          運(yùn)行效果:


          主站蜘蛛池模板: 日韩人妻精品一区二区三区视频| 国产成人一区二区三区在线观看 | 国产在线一区二区在线视频| 麻豆aⅴ精品无码一区二区| 精品人妻AV一区二区三区| 免费在线观看一区| 精品一区狼人国产在线| 搡老熟女老女人一区二区| 久久se精品一区精品二区| 福利视频一区二区牛牛| 国产福利酱国产一区二区| 久久精品无码一区二区WWW| 深夜福利一区二区| 韩国精品一区视频在线播放| 91久久精品国产免费一区| 亚洲AV无码一区二区二三区软件| 日本一区二区三区在线视频| 亚洲欧美日韩一区二区三区| 麻豆果冻传媒2021精品传媒一区下载| 中文字幕一区二区三区精华液| 激情啪啪精品一区二区| 国产亚洲福利一区二区免费看| 亚洲熟女综合一区二区三区| 毛片一区二区三区| 国产激情一区二区三区小说| 国产成人精品第一区二区| 日韩精品一区二区三区老鸭窝| 中文字幕一区二区精品区| 射精专区一区二区朝鲜| 久久久av波多野一区二区| 麻豆文化传媒精品一区二区| 色狠狠一区二区三区香蕉| 一区二区和激情视频| 成人精品视频一区二区| 国产精品视频免费一区二区三区| 日韩精品一区二区三区毛片 | 97精品国产一区二区三区| 曰韩人妻无码一区二区三区综合部| 亚洲一区免费视频| 欧美日韩精品一区二区在线视频| 精品国产高清自在线一区二区三区|