利用原生JS实现类似浏览器查找高亮功能(转载)

利用原生JS实现类似浏览器查找高亮功能(转载)

利用原生JS实现类似浏览器查找高亮功能

在完成 Navify 时,增加一个类似浏览器ctrl+f查找并该高亮的功能,在此进行一点总结:

需求

.content中有许多.box,需要在.box中找出搜索的字符串,再将无搜索结果的.box隐藏掉,此外还要将字符串高亮。这个页面用vue.js实现了数据交互,不想用jquery来实现得查找高亮功能,得用原生js来实现该功能。

原理

将各个.box的文本内容提取,利用正则判断是否匹配字符串,若无搜索字符串,则隐藏该.box;否则继续找到具体的与该字符串匹配的结点及文本。通过对父节点的childNodes,然后利用nodeType筛选出文本结点,并利用匹配字符串将该文本结点分割,然后给匹配字符串加上<span class="search-highlight">,同时将原文本结点放入<template>中暂存,最后一起拼接后插入替换匹配结点。
更改或删除搜索的字符串时,将去掉.search-highlight,遍历所有的.search-highlight,找到里面父节点中的<template>,将<template>内容与父节点的内容替换,从而达到复原的效果。

思路&代码

// 原生事件监听
document.querySelector("search").addEventListener('input', function(e){ var target = e.target, value = target.value; // value即搜索的字符串 const text = String(value).trim(); const reg = new RegExp(text, 'ig'); // 匹配全局大小写 const content = document.querySelector('.content'); const box = document.querySelectorAll('.box'); this.rmHighlight(content); // 移除所有之前的高亮内容 box.forEach((el) => { // 遍历.box el.classList.remove('hidden'); // 清除之前无搜索结果时隐藏的.box if (!text) return; // 如果搜索的字符串为空,不进行下列操作 let match = false; // 该box内是否含有匹配内容 const range = el.querySelectorAll('.section-heading, .list-title, .item-name'); // 可搜索区域 range.forEach((item) => { if (item.innerText.match(reg)) { this.highlight(item, text); // 目标结点匹配则执行高亮标记函数 match = true; } }); if (!match) { // 是否有匹配,从而对.box进行隐藏 el.classList.add('hidden'); } else { el.classList.remove('hidden'); } }); } 
// highlight函数
function highlight(el, value){ const childList = el.childNodes; if (!childList.length || !value.length) return; // 无子节点或无查询值,则不进行下列操作 const reg = new RegExp(value, 'ig'); childList.forEach((el) => { // 遍历其内子节点 if (el.nodeType === 1 // 如果是元素节点 && el.classList && !el.classList.contains('search-highlight') // 而且没有被标记高亮 && !/(script|style|template)/i.test(el.tagName)) { // 并且元素标签不是script或style或template等特殊元素 this.highlight(el, value); // 那么就继续遍历(递归)该元素节点 } else if (el.nodeType === 3) { // 如果是文本节点 const highlightList = el.data.match(reg); // 得出文本节点匹配到的字符串数组 if (!highlightList) return; const splitTextList = el.data.split(reg); // 分割多次匹配 // 遍历分割的匹配数组,将匹配出的字符串加上.highlight并依次插入DOM el.parentNode.innerHTML = splitTextList.reduce( (html, splitText, i) => html + splitText + ( (i < splitTextList.length - 1) ? `<span class="search-highlight">${highlightList[i]}</span>` : `<template search-highlight>${el.data}</template>` ), // 同时给为匹配的template用于后续恢复 ''); } }); } 
// 移除.highlight函数
function rmHighlight(el) { const highlightSpans = el.querySelectorAll('span.search-highlight'); highlightSpans.forEach((el) => { // 找到所有.highlight并遍历 if (!el.parentNode) return; const template = el.parentNode.querySelector('template[search-highlight]'); if (!template) return; // 找到父节点中的template,将自己内容替换为template内容 el.parentNode.innerHTML = el.parentNode.querySelector('template[search-highlight]').innerHTML; }); } 

完整代码参见 navify (Github)

posted @ 2019-03-11 22:00 灵风博客 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现前端页面的搜索功能,可以使用以下步骤: 1. 获取页面上的所有需要搜索的内容,可以是文本、链接、图片等等。 2. 创建一个搜索框,用于用户输入搜索关键词。 3. 监听搜索框的输入事件,获取用户输入的关键词。 4. 遍历页面的所有需要搜索的内容,使用JavaScript的正则表达式匹配用户输入的关键词。 5. 如果找到匹配的内容,则将其高亮显示,或者在一个结果列表中显示。 下面是一个简单的示例代码: HTML部分: ```html <input type="text" id="searchBox" placeholder="请输入搜索关键词"> <div id="searchResult"></div> <div> <p>这是一段要搜索的文本</p> <a href="#">这是一个链接</a> <img src="image.jpg" alt="这是一张图片"> </div> ``` JavaScript部分: ```javascript // 获取需要搜索的内容 const content = document.querySelectorAll('p, a, img'); // 监听搜索框的输入事件 const searchBox = document.getElementById('searchBox'); searchBox.addEventListener('input', () => { // 获取用户输入的关键词 const keyword = searchBox.value; // 遍历所有需要搜索的内容 content.forEach(item => { // 使用正则表达式匹配关键词 const regex = new RegExp(keyword, 'gi'); const match = item.textContent.match(regex); // 如果找到匹配的内容,则高亮显示 if (match) { const highlighted = item.textContent.replace(regex, '<span class="highlight">$&</span>'); item.innerHTML = highlighted; } }); // 在结果列表中显示匹配的内容 const searchResult = document.getElementById('searchResult'); searchResult.innerHTML = ''; content.forEach(item => { if (item.textContent.includes(keyword)) { const resultItem = document.createElement('div'); resultItem.textContent = item.textContent; searchResult.appendChild(resultItem); } }); }); ``` CSS部分: ```css .highlight { background-color: yellow; } ``` 当用户输入关键词时,JavaScript会遍历页面上的所有需要搜索的内容,匹配关键词并高亮显示匹配的内容。同时,还会在结果列表中显示匹配的内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值