整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          HTML高亮關鍵字的完美解決方案

          近項目做暈頭,一個接一個,其中遇到這樣的一個功能,在網頁中高亮關鍵字的實現方法,下面小編把實現代碼及解決方案分享給大家,感興趣的的朋友跟隨小編一起看看吧

          最近做項目遇到這樣的一個功能:在網頁中高亮關鍵字。

          本以為一個 innerHTML replace 就能實現的簡單操作,卻遇到了許多的問題。本文就記錄這些問題和最終的完美解決辦法, 希望能對有同樣遭遇的小伙伴有所幫助。只對結果感興趣的,忽略過程,直接跳過看結果吧~

          常用做法:正則替換

          思路:要想高亮元素,那么需要將關鍵字提取出來用標簽包裹,然后對標簽進行樣式調整。使用 innerHTML,或 outHTML, 而不能使用 innerText,outText。

          const regex = new RegExp(keyword,"g")
          element.innerHTML = element.innerHTML.replace(regex,"<b class="a">"+keyword+"</b>")
          element.classList.add("highlight")
          

          這樣做存在的隱患有如下:

          ()\
          div
          <div id="parent">
           <div class="test">test</div>
           </div>
          

          關鍵字父節點 element 通過 class 來進行背景染色處理,對原始DOM有一定程度污染,可能對 element 再次定位造成影響。(作為插件希望盡可能少改變原始DOM)

          正則優化一:僅處理位于標簽內的元素

          var formatKeyword = text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') // 轉義處理keyword包含的特殊字符,如 /.
          var finder = new RegExp(">.*?"++".*?<") // 提取位于標簽內的文本,避免誤操作 class、id 等
           
          element.innerHTML = element.innerHTML.replace(finder,function(matched){
           return matched.replace(text,"<br>"+text+</br>)
          })// 對提取的標簽內文本進行關鍵字替換
          

          以能解決大多數問題,但依舊存在的問題是,只要標簽屬性存在類似 < 符號,將會打破匹配規則導致正則提取內容錯誤, HTML5 dataset 可以自定義任意內容,故這些特殊字符是無法避免的。

          <div dataset="p>d">替換</div>
          

          正則優化二:清除可能影響的標簽

          <div id="keyword">keyword</div>
           =》將閉合標簽用變量替換
           [replaced1]keyword[replaced2]//閉合標簽內 id="keyword" 不會被處理
           =》
           [replaced1]<b>keyword</b>[replaced2]
           =》將暫存變量 replaced 替換為原先標簽
           <div id="keyword"><b>keyword</b></div>
          
          • 這種思路及源碼從這里來, 但存在問題是:
          • 如果 [replaced1] 包含 keyword, 那么替換時將發生異常

          最重要的,當標簽值中包含 <> 符號時,此方法也不能正確的提取標簽

          總之在經過了N多嘗試之后,通過正則都沒能有效的處理各種情況。然后換了個思路,不通過字符串的方式,通過節點處理。element.childNodes 可以最有效的清理標簽內的干擾信息。

          [完美解決方案]通過 DOM 節點處理

          <div id="parent">
           keyword 1
           <span id="child">
           keyword 2
           </span>
           </div>
          

          通過 parent.childNodes 得到所有子節點。child 節點可以通過 innerText.replce(keyword,result) 的方式替換得到想要的高亮效果,如下: <span id="child"><b>keyword</b> 2</span> (遞歸處理:當child節點不含子節點時進行replace操作)。

          但是 keyword 1 是屬于文本節點,只能修改文本內容,無法增加 HTML,更無法單獨控制其樣式。而文本節點也不能轉換為普通節點,這也是最苦惱的事情。

          最后~,本文的重點來了,因為這個功能,讓我第一次認真接觸到了文本節點這個東西。從這里發現了Text,使用切割文本節點并替換的方式實現高亮。

          源碼以及還原高亮見源碼

          const reg = new RegExp(keyword.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'))
          highlight = function (node,reg){
           if (node.nodeType == 3) { //只處理文本節點
           const match = node.data.match(new RegExp(reg));
           if (match) {
           const highlightEl = document.createElement("b");
           highlightEl.dataset.highlight="y"
           const wordNode = node.splitText(match.index)
           wordNode.splitText(match[0].length); // 切割成前 關鍵詞 后三個Text 節點
           const wordNew = document.createTextNode(wordNode.data);
           highlightEl.appendChild(wordNew);//highlight 節點構建成功
           wordNode.parentNode.replaceChild(highlightEl, wordNode);// 替換該文本節點
           }
           } else if (node.nodeType == 1 && node.dataset.highlight!="y"
           ) {
           for (var i = 0; i < node.childNodes.length; i++) {
           highlight(node.childNodes[i], reg);
           i++
           }
           } 
          }
          

          總結

          以上所述是小編給大家介紹的HTML高亮關鍵字的完美解決方案,希望對大家有所幫助,

          學習從來不是一個人的事情,要有個相互監督的伙伴,想要學習或交流前端問題的小伙伴可以私信“學習”小明加群獲取2019web前端最新入門資料,一起學習,一起成長!

          辛萬苦寫了篇技術分享,貼了一堆代碼,興高采烈地發到了自己的博客網站上。結果卻發現代碼全是白底黑字,字體還難看得很,你瞬間就沒了興致。能不能讓網頁也能像 IDE 那樣,做帶語法高亮的炫酷顯示呢?來看一看 Highlight.js 吧,看這個語法高亮庫如何點亮你的代碼。

          Highlight.js

          簡介

          Highlight.js,是在 Github 上由 highlight.js 組織開源的前端代碼語法高亮庫,代碼倉庫在 https://github.com/highlightjs/highlight.js,目前版本為 10.1.0。其不依賴于任何框架,自帶對于大量編程語言和標記語言的語法高亮規則,和主流的高亮色彩方案,且可以自由擴展。其支持自動語言檢測,使用極為方便,是在網頁上進行語法高亮的不二之選。

          highlight.js語法高亮庫

          安裝

          Highlight.js 的 CSS 文件的選擇決定高亮配色方案,默認為 Default,另外還有如 Monokai Sublime、Ocean、Solarized Dark、Tomorrow 等經典的主流配色方案。

          而 JS 文件的選擇決定可以支持的語言。主要的 highlight.min.js 包含了一些主流的語言,包括 C++、XML、Markdown、Java 等。如果需要一些其他的語言,則要另外引用該語言對應JS文件。

          Highlight.js 在瀏覽器中可以簡單的引用 CDN 來使用:

          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.0/styles/default.min.css">
          <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.0/highlight.min.js"></script>

          示例

          Highlight.js 使用十分簡單,在引用了 CSS 和 JS 后,執行

          hljs.initHighlightingOnLoad();

          Highlight.js就會自動查找網頁中以標簽 pre 和 code 所包裹的代碼

          <pre><code>...</code></pre>

          并自動檢測代碼語言,進行高亮渲染。我們也可以為 code 標簽添加語言名稱的 class,來顯式地標明代碼語言。我們可以看一個使用示例,注意實際代碼中尖括號等 HTML 轉義字符需要進行轉義處理:

          <html>
          <head>
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.0/styles/monokai-sublime.min.css">
            <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.0/highlight.min.js"></script>
          </head>
          <body>
            <pre><code class="cpp">#include <iostream>
          
          int main(int argc, char *argv[]) {
          
              /* An annoying "Hello World" example */
              for (auto i = 0; i < 0xFFFF; i++)
                  cout << "Hello, World!" << endl;
          
              char c = '\n';
              unordered_map <string, vector<string> > m;
              m["key"] = "\\\\"; // this is an error
          
              return -2e3 + 12l;
          }
            </code></pre>
            <script>
              hljs.initHighlightingOnLoad();
            </script>
          </body>
          </html>

          該網頁對于 C++ 語言片段使用了 Monokai Sublime 主題進行了語法高亮渲染:

          使用Highlight.js渲染C++代碼

          可以看到,包括關鍵字、注釋和字面值等都有了不同顏色的渲染,輸出十分美觀。以下則是使 Dracula 主題對 Javascript 代碼渲染的例子:

          使用Highlight.js渲染Javascript代碼

          我們也可以不使用 pre 和 code 標簽來包裹代碼,改為使用自定義的容器,使用時需要注意換行和等寬字體的問題。

          document.querySelectorAll('div.code').forEach((block) => {
            hljs.highlightBlock(block);
          });

          在渲染大量代碼時,為避免瀏覽器卡死,可以使用 Web Worker 來在后臺進行渲染:

          // index.html
          addEventListener('load', () => {
            const code = document.querySelector('#code');
            const worker = new Worker('worker.js');    // 新建Worker
            worker.onmessage = (event) => { code.innerHTML = event.data; }    // 接受渲染后的HTML
            worker.postMessage(code.textContent);    // 傳遞代碼
          });
          // worker.js
          onmessage = (event) => {
            importScripts('<path>/highlight.min.js');
            const result = self.hljs.highlightAuto(event.data);    // 高亮渲染
            postMessage(result.value);    // 返回HTML
          };

          總結

          Highlight.js 使得在前端頁面進行語法高亮變得十分方便,為在網頁顯示的代碼增添了顏色和生機。

          Highlight.js 文檔詳盡,設計簡潔,為編寫新的語言支持和配色方案提供了很大支持,定制化能力和可擴展性極強。Highlight.js 的代碼包含了對于各種語言的語法解析,和不同配色方案的設計,對于對編程語言和語法高亮領域感興趣的開發者是一座珍貴的寶庫。

          行代碼就能讓我的網站支持代碼高亮的工具庫,也支持在 Vue 中使用,強烈推薦給大家。

          關于 highlight.js

          highlight.js 是一款使用 javascript 開發代碼高亮工具庫,能夠讓網頁上的代碼顯示接近我們使用的代碼編輯器的高亮樣式,從而看起來更舒服,增強閱讀體驗。

          highlight.js 官網截圖

          highlight.js 的技術特性

          • 支持 197 種開發語言和 246 種代碼高亮風格主題
          • 自動開發語言檢測
          • 支持多種語言混合代碼同時高亮
          • 支持任何 HTML 標簽,不僅僅是<code></code>
          • 支持 npm 安裝,可以在 Vue.js 中使用,也可以在 node.js 中使用
          • 無依賴,與任何 js 框架兼容

          為什么要用 highlight.js

          常來我網站的小伙伴都知道,我的文章有一個欄目是“前端”,主要推薦一下實用的前端開源項目或者組件庫,寫技術類文章免不了要貼代碼,我的網站基于 wordpress 搭建,此前我一直為找一款代碼高亮插件煩惱,但大部分 wordpress 的代碼高亮插件實在太臃腫,出來的樣式又不美觀。大多時候是截圖 VsCode 的代碼界面,甚至還用過 codepng 這個工具把代碼變成圖片貼在文章中,但這樣做是美觀了,但也存在2個問題:

          • 長代碼圖片會縮放,閱讀體驗不佳
          • 搜索引擎不識別,對 SEO 不友好

          最終還是找到了 highlight.js,完美解決了上面兩個問題,而且配置簡單,演示漂亮,定制化簡單。不禁感嘆:用純前端的方式解決,才能精準控制,實現想要的效果。

          使用教程:為我的網站添加代碼高亮功能

          下面以我的網站為例,展示將 highlight.js 用在我們的項目上的方法。首先 highlight.js 支持 cdn 直接引入和 npm 安裝,我的網站基于 wordpress 開發,主題是自己寫的,最簡單的方式就是在文章詳情頁引入 highlight.js 和主題樣式。

          雖然 highlight.js 支持幾百種開發語言,但為了將文件體積控制到最小,我們可以點擊“get version”按鈕進入下載頁,通過勾選我們需要的開發語言,來構建最輕量的庫。

          下載解壓后得到的 highlight.min.js 就是我們需要引入的 js 文件,主題樣式都在 style 文件夾里,我選擇了一個比較喜歡的 monokai-sublime 主題,只需要一個 css 文件,然后初始化:

          <link href="/js/monokai-sublime.min.css" rel="stylesheet" type="text/css">
          <script src="/js/highlight.min.js"></script>
          <script>
             hljs.highlightAll();
          </script>

          就是這么簡單,highlight.js 會自動將文章中的 <pre><code></code></pre> 代碼進行識別語言并且高亮,一切就是這么簡單。為了讓代碼顯示更協調,我用幾行 css 控制了包裹層的圓角以及背景顏色、字體大小等,大功告成。

          .post-content .wp-block-code {
             background-color: #F6F8FF;
             border-radius: 16px;
             font-size: 16px;
             padding: 22px 22px 22px 38px;
             margin-top: 22px;
             margin-bottom: 22px;
          }
          .post-content .wp-block-code {
             line-height: 1.2;
             font-size: 15px;
             padding: 10px;
             overflow-x: auto;
          }
          .post-content .wp-block-code code {
             position: relative;
             background-color: unset !important;
          }

          當然 highlight.js 也能在 vue 項目中使用,安裝:

          npm install highlight.js

          在 Vue 文件中使用 (通過 highlight.js for Vue ) :

          <div id="app">
            <!-- bind to a data property named `code` -->
            <highlightjs autodetect :code="code" />
            <!-- or literal code works as well -->
            <highlightjs language='javascript' code="var x = 5;" />
          </div>

          需要注意的是,自動識別模式不能100%識別出代碼所屬的開發語言,識別錯誤會導致高亮樣式是別的語言的,這種情況下可以手動設置一個 class 來精準控制:

          <pre><code class="language-javascript">...</code></pre>

          官網提供了詳盡的使用文檔,有更多代碼高亮的控制,但不足的就是 highlight.js 沒有顯示行號的支持,需要通過再引入一個庫 (highlightjs-line-numbers.js) 或者自行實現。

          免費開源說明

          highlight.js 是一款基于 BSD 許可證開源的 javascript 工具庫,任何個人和公司都可以免費下載用于自己的項目,包括商用項目。

          關注我,持續分享高質量的免費開源、免費商用的資源。

          ↓↓點擊查看本次分享的網址以及代碼高亮效果

          highlight.js - 讓網頁上的代碼高亮美化的免費開源工具庫|那些免費的磚


          主站蜘蛛池模板: 国产高清在线精品一区小说 | 久久无码一区二区三区少妇| 日韩AV在线不卡一区二区三区| 福利一区二区三区视频在线观看| 亚洲A∨精品一区二区三区下载| 国99精品无码一区二区三区| 亚洲一区二区三区无码影院| 国产精品一区二区香蕉| 无码人妻一区二区三区一| 日本不卡一区二区三区视频| 中文字幕一区二区三区在线播放| 亚洲日韩一区二区三区| 日产精品久久久一区二区| 国产日韩精品一区二区三区在线| 精品福利一区3d动漫| 午夜在线视频一区二区三区| 无码中文人妻在线一区| 亚洲熟女乱色一区二区三区| 韩国一区二区视频| 国产精品分类视频分类一区| 久久久久无码国产精品一区| 亚洲av无码一区二区三区乱子伦| 国产美女精品一区二区三区| 成人精品视频一区二区三区不卡| 国产福利一区二区在线视频| jizz免费一区二区三区| 色欲AV无码一区二区三区| 午夜无码一区二区三区在线观看| 日韩精品久久一区二区三区| 精品不卡一区中文字幕 | 国产AV天堂无码一区二区三区| 久久精品无码一区二区三区免费 | 国产一区二区三区久久精品| 曰韩精品无码一区二区三区| 中文字幕精品一区二区精品| 久久高清一区二区三区| 中文字幕乱码人妻一区二区三区| 欧亚精品一区三区免费| 精品一区精品二区| 国99精品无码一区二区三区 | 国内精品一区二区三区东京 |