一直都想做一个js库,而且github上没有太多重复的轮子那种(轮子太多自己造就没必要了),最好是自己会用得上。思前想后,决定做一个高亮文字的js库。刚好最近接触一段时间typescript,可以拿来练练手,毕竟自己的东西怎么折腾都可以。
如何让一个元素的文字高亮,或者鼠标选中的文字高亮?
- 让一个元素的文字高亮很简单,直接
<p>这是一段文字</p> ==> <p><mark>这是一段文字</mark></p>
可以为元素内的文字加上一个容器,并且不能够影响到文字的换行。之后为mark元素加上样式就可以了
- 让鼠标选中的文字高亮
高亮鼠标选中的文字需要处理的情况就复杂一点了
例如
jsfiddle例子
- 当鼠标选中一个元素中的部分文字
// 鼠标选中了在p元素中的一部分文字,假设是 “一段” 这两个字
// 那么则需要处理成以下模样
<p>这是一段文字</p> ==> <p>这是<mark>一段</mark>文字</p>
- 鼠标选中的文字跨越多个元素
<div>
<p>1这是一段文字</p>
</div>
<div>
<p>2这是一段文字</p>
</div>
处理以上的这些情况,则需要用到Range对象
document.addEventListener('click', (event) => {
let selection = window.getSelection();
console.log(selection)
if (selection.rangeCount) {
let range = selection.getRangeAt(0)
console.log(range)
}
})
我们可以通过Selection对象进而拿到Range.在chrome上我们用鼠标只能选中一个Range,firefox上按住ctrl则可以多选。
Range.extractContents()
把 Range 的内容从文档树移动到文档片段中。这会造成选区内的元素消失在dom树上
Range.insertNode()
在 Range 的起点处插入节点。
通过Range.extractContents()可以拿到documentFragment,之后对document Fragment进行相应的处理之后插入到Range中。
但是简单的进行insertNode会发生换行的效果。
具体原因看看代码就知道了。
例子中的p元素插入到Range时,包含了其父元素div,所以发生换行。
所以这里面还是有很多坑要踩,下次有空再写吧。
最后附上自己的写的js库,虽然还有很多待完善的地方。喜欢就给个start吧。