HTML表格如何實現(xiàn)數(shù)據(jù)的模糊搜索?有哪些方法?

實現(xiàn)html表格數(shù)據(jù)的模糊搜索,最常見方法是使用JavaScript進行dom操作,通過監(jiān)聽輸入事件實時篩選并顯示匹配行。1. 基本實現(xiàn):獲取用戶輸入,遍歷表格每一行和單元格,判斷內(nèi)容是否包含關(guān)鍵詞,動態(tài)設置行的顯示或隱藏;2. 性能優(yōu)化:對大數(shù)據(jù)量表格,采用節(jié)流/防抖機制延遲執(zhí)行搜索函數(shù),減少頻繁觸發(fā);3. 進階優(yōu)化:將表格數(shù)據(jù)提取到數(shù)組中,減少dom訪問頻率;4. 更智能的模糊搜索:引入編輯距離算法或使用fuse.JS等庫,提升匹配準確性和容錯能力;5. 后端搜索優(yōu)勢:適用于海量、敏感或需多用戶協(xié)作的場景,借助數(shù)據(jù)庫或全文搜索引擎(如elasticsearch)處理復雜查詢,減輕前端壓力,提高可擴展性與安全性。

HTML表格如何實現(xiàn)數(shù)據(jù)的模糊搜索?有哪些方法?

實現(xiàn)HTML表格數(shù)據(jù)的模糊搜索,最常見且直接的方法是利用JavaScript在客戶端進行DOM操作,通過監(jiān)聽用戶輸入,實時篩選并顯示或隱藏表格行。這本質(zhì)上就是前端邏輯對頁面內(nèi)容的動態(tài)調(diào)整。

HTML表格如何實現(xiàn)數(shù)據(jù)的模糊搜索?有哪些方法?

解決方案

說白了,核心思路就是拿到用戶的搜索詞,然后遍歷表格里的每一行(

),再遍歷每一行里的每個單元格(

),看看單元格的文本內(nèi)容是不是包含了搜索詞。如果包含了,那這行就顯示出來;如果沒有,就把它藏起來。這個過程需要一點JavaScript代碼來驅(qū)動。

比如,我們有一個簡單的HTML表格和搜索框:

立即學習前端免費學習筆記(深入)”;

HTML表格如何實現(xiàn)數(shù)據(jù)的模糊搜索?有哪些方法?

<input type="text" id="searchInput" onkeyup="searchTable()"> <table id="myTable">   <thead>     <tr>       <th>姓名</th>       <th>城市</th>       <th>職業(yè)</th>     </tr>   </thead>   <tbody>     <tr>       <td>張三</td>       <td>北京</td>       <td>工程師</td>     </tr>     <tr>       <td>李四</td>       <td>上海</td>       <td>設計師</td>     </tr>     <tr>       <td>王五</td>       <td>廣州</td>       <td>產(chǎn)品經(jīng)理</td>     </tr>     <tr>       <td>趙六</td>       <td>北京</td>       <td>銷售</td>     </tr>   </tbody> </table>  <script> function searchTable() {   let input, filter, table, tr, td, i, j, txtValue;   input = document.getElementById("searchInput");   filter = input.value.toUpperCase(); // 轉(zhuǎn)換為大寫,方便不區(qū)分大小寫搜索   table = document.getElementById("myTable");   tr = table.getElementsByTagName("tr");    // 遍歷所有表格行,從索引1開始跳過表頭   for (i = 1; i < tr.length; i++) {     let rowVisible = false; // 標記當前行是否應該顯示     // 遍歷當前行的所有單元格     td = tr[i].getElementsByTagName("td");     for (j = 0; j < td.length; j++) {       if (td[j]) {         txtValue = td[j].textContent || td[j].innerText; // 獲取單元格文本         if (txtValue.toUpperCase().indexOf(filter) > -1) { // 判斷是否包含搜索詞           rowVisible = true;           break; // 找到一個匹配就夠了,跳出單元格循環(huán)         }       }     }     if (rowVisible) {       tr[i].style.display = ""; // 顯示行     } else {       tr[i].style.display = "none"; // 隱藏行     }   } } </script>

這段代碼就是最基礎的實現(xiàn),它通過onkeyup事件監(jiān)聽用戶輸入,每次按鍵都重新過濾表格。

如何優(yōu)化大型HTML表格的模糊搜索性能?

當表格數(shù)據(jù)量比較大,比如幾百上千行的時候,每次按鍵都遍歷整個DOM樹進行搜索和修改樣式,用戶體驗可能會變差,頁面會顯得卡頓。所以,優(yōu)化是很有必要的。

HTML表格如何實現(xiàn)數(shù)據(jù)的模糊搜索?有哪些方法?

我個人覺得,最直接有效的優(yōu)化方式是“節(jié)流”或“防抖”。說白了,就是不要用戶每敲一個鍵就立即執(zhí)行搜索,而是等用戶停下來或者在一定時間內(nèi)只執(zhí)行一次。比如,可以用setTimeout來延遲執(zhí)行搜索函數(shù),如果在延遲時間內(nèi)用戶又輸入了,就取消之前的延遲,重新計時。

let searchTimeout; function searchTableOptimized() {   clearTimeout(searchTimeout); // 清除之前的延遲   searchTimeout = setTimeout(() => {     // 這里放上面 searchTable() 函數(shù)里的所有邏輯     let input, filter, table, tr, td, i, j, txtValue;     input = document.getElementById("searchInput");     filter = input.value.toUpperCase();     table = document.getElementById("myTable");     tr = table.getElementsByTagName("tr");      for (i = 1; i < tr.length; i++) {       let rowVisible = false;       td = tr[i].getElementsByTagName("td");       for (j = 0; j < td.length; j++) {         if (td[j]) {           txtValue = td[j].textContent || td[j].innerText;           if (txtValue.toUpperCase().indexOf(filter) > -1) {             rowVisible = true;             break;           }         }       }       tr[i].style.display = rowVisible ? "" : "none";     }   }, 300); // 延遲300毫秒執(zhí)行 } // 將 onkeyup="searchTable()" 改為 onkeyup="searchTableOptimized()"

另外,如果表格數(shù)據(jù)是固定的,可以在頁面加載時,把所有行的數(shù)據(jù)提前提取出來,存到一個JavaScript數(shù)組里。搜索的時候,就直接操作這個數(shù)組,找到匹配的行的索引,然后只對這些索引對應的DOM行進行顯示/隱藏操作。這樣可以避免每次都從DOM中讀取文本內(nèi)容,減少DOM操作次數(shù)。

對于更復雜的場景,一些成熟的JavaScript庫,比如DataTables.js或者List.js,它們內(nèi)部已經(jīng)做了大量的性能優(yōu)化,包括高效的DOM操作、虛擬滾動(只渲染可視區(qū)域的行)等,用起來會省心很多。它們通常提供更強大的搜索、排序和分頁功能。

除了簡單的包含匹配,還有哪些更“智能”的模糊搜索算法?

我們上面用的indexOf()或者includes()方法,只能實現(xiàn)精確的“包含”匹配。但有時候用戶可能會打錯字,或者希望搜索結(jié)果更“智能”一點,這時候就需要更高級的模糊匹配算法了。

一種常見的“智能”算法是基于編輯距離(Levenshtein distance)的匹配。它計算一個字符串轉(zhuǎn)換成另一個字符串所需的最少單字符編輯操作(插入、刪除、替換)次數(shù)。次數(shù)越少,說明兩個字符串越相似。你可以設置一個閾值,比如編輯距離小于等于2的都認為是匹配的。當然,計算編輯距離會比簡單的包含匹配消耗更多性能,所以需要權(quán)衡。

另一個我個人比較喜歡的方式是使用專門的模糊搜索庫,比如Fuse.js。它不僅僅是基于編輯距離,還會考慮字符的順序、位置、模式匹配等多種因素,給出更“人性化”的匹配結(jié)果。比如,搜索“北京”,它可能也能匹配到“京北”或者“北景”之類的,并給出一個相關(guān)性分數(shù)。

// 以Fuse.js為例 (需要引入Fuse.js庫) // npm install fuse.js 或者通過CDN引入 /* <script src="https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.min.js"></script> */  // 假設我們有一個數(shù)據(jù)數(shù)組,而不是直接從DOM讀取 const tableData = [   { name: '張三', city: '北京', occupation: '工程師' },   { name: '李四', city: '上海', occupation: '設計師' },   { name: '王五', city: '廣州', occupation: '產(chǎn)品經(jīng)理' },   { name: '趙六', city: '北京', occupation: '銷售' }, ];  // Fuse.js 配置 const options = {   keys: ['name', 'city', 'occupation'], // 告訴Fuse在哪些字段里搜索   includeScore: true, // 是否包含匹配分數(shù)   threshold: 0.4, // 匹配閾值,0表示完美匹配,1表示完全不匹配 };  const fuse = new Fuse(tableData, options);  function searchTableFuzzy() {   let input = document.getElementById("searchInput");   let query = input.value;   let table = document.getElementById("myTable");   let tr = table.getElementsByTagName("tr");    if (query.trim() === '') {     // 如果搜索框為空,顯示所有行     for (let i = 1; i < tr.length; i++) {       tr[i].style.display = "";     }     return;   }    const result = fuse.search(query); // 執(zhí)行模糊搜索    // 根據(jù)搜索結(jié)果顯示或隱藏行   const matchedIndices = new Set(result.map(item => tableData.indexOf(item.item)));    for (let i = 1; i < tr.length; i++) {     // 這里的 i-1 是因為 tr[0] 是表頭,而 tableData 是從0開始的     if (matchedIndices.has(i - 1)) {       tr[i].style.display = "";     } else {       tr[i].style.display = "none";     }   } } // 將 onkeyup="searchTableOptimized()" 改為 onkeyup="searchTableFuzzy()"

這種方式需要先將表格數(shù)據(jù)轉(zhuǎn)換成JS對象數(shù)組,這在數(shù)據(jù)量大時,一次性提取和構(gòu)建索引的開銷是值得的。

在后端實現(xiàn)表格數(shù)據(jù)模糊搜索有什么優(yōu)勢和場景?

到目前為止,我們聊的都是客戶端的模糊搜索。但很多時候,尤其是數(shù)據(jù)量巨大(比如幾十萬、幾百萬甚至上億條記錄)或者需要多用戶實時協(xié)作的場景,純粹的客戶端搜索就不太現(xiàn)實了。這時候,后端搜索就成了唯一的選擇。

后端實現(xiàn)模糊搜索,最大的優(yōu)勢就是可伸縮性處理復雜查詢的能力。所有的數(shù)據(jù)都存儲在數(shù)據(jù)庫里,搜索邏輯在服務器端執(zhí)行,客戶端只需要發(fā)送一個搜索請求,服務器返回過濾好的數(shù)據(jù)。

主要優(yōu)勢:

  1. 處理海量數(shù)據(jù): 數(shù)據(jù)庫天生就是為存儲和檢索大量數(shù)據(jù)而設計的。客戶端內(nèi)存和計算能力有限,不可能把所有數(shù)據(jù)都加載到瀏覽器里。
  2. 安全性: 數(shù)據(jù)不需要全部暴露給客戶端,只有符合條件的數(shù)據(jù)才會被發(fā)送過來。
  3. 復雜查詢: 數(shù)據(jù)庫查詢語言(sql)或者專業(yè)的搜索引擎(如Elasticsearch、solr)能處理比前端復雜得多的組合查詢、全文搜索、相關(guān)性排序等。
  4. 減輕客戶端負擔: 所有的計算都在服務器端完成,客戶端只負責展示,用戶體驗更流暢。

常見場景:

  • 電商網(wǎng)站的商品搜索: 動輒百萬千萬的商品數(shù)據(jù),必須在后端進行高效搜索。
  • 大型企業(yè)內(nèi)部系統(tǒng): 員工信息、客戶資料、項目文檔等,數(shù)據(jù)量龐大且敏感,需要后端權(quán)限控制和搜索。
  • 日志分析平臺: 實時查詢和過濾海量的日志數(shù)據(jù)。

實現(xiàn)方式: 在后端,最常見的模糊搜索方式是利用數(shù)據(jù)庫的LIKE操作符,比如SQL中的select * FROM users WHERE name LIKE ‘%張%’;。但LIKE操作在數(shù)據(jù)量大時性能很差,尤其是在開頭使用通配符(%)時,因為它無法利用索引。

更高效的后端模糊搜索通常會使用專門的全文搜索引擎,如Elasticsearch、Solr,或者數(shù)據(jù)庫自帶的全文檢索功能(如postgresql的tsquery)。這些工具會提前對數(shù)據(jù)進行索引,構(gòu)建倒排索引等結(jié)構(gòu),使得模糊搜索和復雜查詢變得極其快速和高效。它們甚至能支持更高級的模糊匹配、同義詞、拼寫糾錯等功能。

所以,在做技術(shù)選型時,如果你的表格數(shù)據(jù)是動態(tài)加載的,并且數(shù)據(jù)量可能很大,那么后端搜索絕對是更穩(wěn)健、更可擴展的方案。客戶端搜索更適合靜態(tài)數(shù)據(jù),或者數(shù)據(jù)量可控的場景。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊10 分享