浏览器中搜索与高亮文本
2017-01-09 17:09
471 查看
在前段时间开发中, 遇到了搜索和高亮文本的需求. 希望开发一个通用的基于html的搜索与高亮模块,
不但能够应用在编辑器中, 而且也能在普通的HTML页面中使用.
mark.js 和 一些文章, 如纯客户端页面关键字搜索高亮jQuery插件 张鑫旭-鑫空间-鑫生活, 发现思路基本如下:
收集搜索目标容器的innerHTML
对innerHtml字符串进行处理, 如关键字正则匹配
将处理后的html更新至目标容器的innerHTML
mark.js 做得得更精细些, 但也会修改搜索区域的DOM结构 – 这是我不希望看到的.
个人希望搜索与高亮模块能够满足:
像浏览器自带的搜索功能(
能够指定搜索区域的容器, 而不是整个页面(
如 CKEditor, UEditor 都是这么做的.
如上图,
这样做的好处是:
不修改搜索区域的DOM结构
缺陷是:
只能同时显示一个结果, 多个结果时, 只能切换显示.
仔细观察, 且猜测其如何实现会发现:
搜索与高亮的整个页面添加了一个蒙板, 覆盖在页面上方
蒙板遇到关键字区域, 开洞露出关键字, 从而产生高亮效果
可以猜想: 这种实现应该也没有修改搜索区域的DOM结构.
搜索高亮
不修改搜索区域的DOM结构
经过一番思考和coding, 发现以下思路可行:
深度优先遍历&收集搜索区域(container)下所有的textNode节点的相关信息, 并保存在一个数组中.
将数组中所有textNode节点的value 拼凑一个大字符串
搜索关键字时, 在大字符串中搜索, 并记录关键字在大字符串中的出现位置信息(start, end)
将关键字在大字符串的出现位置信息(start, end) 映射成关键字在数组中的textNode节点上的开头结尾信息(start, end)
根据关键字在数组中的textNode节点上的开头结尾信息(start, end), 创建刚好包含关键字的 range (参考 https://developer.mozilla.org/en-US/docs/Web/API/range)
使用 range 的
根据位置信息(top, left, width, height)数组, 在页面中添加半透明高亮层, 使用绝对定位绘制, 使之悬浮在关键字上方.
以下是搜索
如果再优化一下界面, 感觉能实现类似 Safari 浏览器的搜索与高亮效果.
与浏览器原生的搜索与高亮(
无法高亮
Search Keyword Highlighting JavaScript | The Art of Web
纯客户端页面关键字搜索高亮jQuery插件 张鑫旭-鑫空间-鑫生活
Range - Web APIs | MDN
不但能够应用在编辑器中, 而且也能在普通的HTML页面中使用.
普通HTML页面思路
于是看了看市面上的一些搜索与高亮插件, 如mark.js 和 一些文章, 如纯客户端页面关键字搜索高亮jQuery插件 张鑫旭-鑫空间-鑫生活, 发现思路基本如下:
收集搜索目标容器的innerHTML
对innerHtml字符串进行处理, 如关键字正则匹配
将处理后的html更新至目标容器的innerHTML
mark.js 做得得更精细些, 但也会修改搜索区域的DOM结构 – 这是我不希望看到的.
个人希望搜索与高亮模块能够满足:
像浏览器自带的搜索功能(
window.find) 那样, 高亮搜索关键字且不修改搜索区域的DOM结构
能够指定搜索区域的容器, 而不是整个页面(
window.find搜索整个页面, 无法指定搜索范围)
编辑器思路
富文本编辑器中开发搜索与高亮文本时, 一般使用 Selection/Range 对象来高亮文本.如 CKEditor, UEditor 都是这么做的.
如上图,
apollo是搜索关键字, 高亮的
Apollo是使用 Selection/Range 来完成的.
这样做的好处是:
不修改搜索区域的DOM结构
缺陷是:
只能同时显示一个结果, 多个结果时, 只能切换显示.
Safari 浏览器的搜索与高亮
Safari 浏览器的搜索功能挺有意思(如下图).仔细观察, 且猜测其如何实现会发现:
搜索与高亮的整个页面添加了一个蒙板, 覆盖在页面上方
蒙板遇到关键字区域, 开洞露出关键字, 从而产生高亮效果
可以猜想: 这种实现应该也没有修改搜索区域的DOM结构.
新思路
以上搜索与高亮的实现思路各不相同, 能否综利用以满足如下要求呢?搜索高亮
不修改搜索区域的DOM结构
经过一番思考和coding, 发现以下思路可行:
深度优先遍历&收集搜索区域(container)下所有的textNode节点的相关信息, 并保存在一个数组中.
将数组中所有textNode节点的value 拼凑一个大字符串
搜索关键字时, 在大字符串中搜索, 并记录关键字在大字符串中的出现位置信息(start, end)
将关键字在大字符串的出现位置信息(start, end) 映射成关键字在数组中的textNode节点上的开头结尾信息(start, end)
根据关键字在数组中的textNode节点上的开头结尾信息(start, end), 创建刚好包含关键字的 range (参考 https://developer.mozilla.org/en-US/docs/Web/API/range)
使用 range 的
getClientRects()获取关键字在窗口中的位置信息(top, left, width, height)数组, 并变换成关键字在页面中的位置信息(top, left, width, height)数组.
根据位置信息(top, left, width, height)数组, 在页面中添加半透明高亮层, 使用绝对定位绘制, 使之悬浮在关键字上方.
以下是搜索
underscor,
总书记时的效果图:
如果再优化一下界面, 感觉能实现类似 Safari 浏览器的搜索与高亮效果.
与浏览器原生的搜索与高亮(
window.find) 相比, 这种思路的缺陷是:
无法高亮
<input/>,
<textarea/>中的文本
参考
mark.jsSearch Keyword Highlighting JavaScript | The Art of Web
纯客户端页面关键字搜索高亮jQuery插件 张鑫旭-鑫空间-鑫生活
Range - Web APIs | MDN
相关文章推荐
- Android Manifest 用法
- Android学习笔记(二九):嵌入浏览器
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- Basilisk:一个有着经典的外观和扩展的 Firefox 复刻
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- 在Windows 8.1的IE 11中屏蔽双击放大功能
- 回顾 Firefox 历史
- 小白观察:微软释放出其基于 Chromium 的 Edge 浏览器
- HTML5调用摄像头实例
- 本人即将筹备败家日志,敬请期待!
- Powershell 创建炫丽美观的Html报表
- 设计模式---状态模式在web前端中的应用
- Apple官网研究之使用Justify布局导航
- 关于前端的思考与感悟
- 又被事件冒泡坑了一把,这次要彻底弄懂浏览器的事件流
- 移动端点击事件全攻略,这里的坑你知多少?
- $q 实例分析 Angular 中的 Promise