需求
需要像瀏覽器的全域性搜尋一樣,搜尋指定模組的對應值,然後將匹配到的內容新增背景顏色等。
思路
- 需要取到當前指定區域的所有內容
- 然後在取到的內容中找到搜尋的內容加上對應的背景顏色
- 最後在將修改後的內容渲染到頁面上
實現
- 利用innerHTML取到對應模組的內容
- 編寫對應的正規表示式來匹配搜尋的內容
- 利用String.prototype.replace替換匹配到的內容
- 最後在渲染到頁面上
程式碼實現:
let wrap = document.querySelector('.wrap');
let innerHTML = wrap.innerHTML;
let reg = new RegExp(query, 'g');
innerHTML = innerHTML.replace(reg, '<span style="color: #000; background-color: #e3e4e5">' + query + '</span>');
wrap.innerHTML = innerHTML;
複製程式碼
具體的實現搜尋實現就完成了,但是上面程式碼還有個缺陷,就是更換搜尋內容時,之前搜尋的內容還是具有選中的樣式,那麼接下來完善功能:
let preQuery = ''; // 上一次搜尋的內容
let wrapDom = ''; // 搜尋區域的dom元素
function searchFn(dom, query) {
let wrap = wrapDom || document.querySelector(dom);
let innerHTML = wrap.innerHTML;
if (!preQuery) {
let preReg = new RegExp('<span style="color: #000; background-color: #e3e4e5">' + preQuery + '</span>', 'g');
innerHTML = innerHTML.replace(preReg, preQuery);
}
if (query) {
let reg = new RegExp(query, 'g');
innerHTML = innerHTML.replace(reg, '<span style="color: #000; background-color: #e3e4e5">' + query + '</span>');
}
wrap.innerHTML = innerHTML;
preQuery = query;
}
複製程式碼
至此搜尋高亮的功能就已經實現了。
注意事項
-
搜尋區域的dom元素中不能使用title屬性,因為當使用title屬性時也會把對應的title屬性內容替換,頁面渲染時就會產生問題,其實可以將匹配規則的正規表示式重寫,但是能力有限,不知道如何編寫排除title屬性的正規表示式
-
如果使用Vue等框架編寫時,搜尋完之後vue相關的事件和屬性全都失效了,因為我們這樣是直接把dom給換了,這種情況下有兩種解決方法:
-
- 搜尋完成之後,再例項化一次vue
function resetVm() { vm.destroy() vm = new Vue({...}) } 複製程式碼
但是這樣會有個問題,重新例項化vue例項之後,搜尋內容就沒了
-
- 不使用vue,可以用jQuery去實現頁面,這樣就不會有事件失效的問題
-