- 在之前的基础上,添加鼠标选中文字,编辑框失焦,再点击加粗的功能
实现思路:编辑失焦时,获取当前的
range
对象,点击加粗按钮时,根据 range 对象提供的setStart
和setEnd
等一些核心 API 以及selection
对象的addRange
配合选中之前的文字,从而达到效果。
刚开始对以上提到的 API 不太了解,想的是,把当前这个选中状态存一份,那失焦的时候就不愁拿不到啦,emmm ....,网上去各种搜索,看 MDN 等,知道 range
对象是会保存上一次的选中状态的,那就好办啦!但是但是,失焦事件在内容区content组件中,而功能实现在toolbar组件中,这不就是兄弟组件之间的传值吗???突然想念 vuex 和 event bus ...,这里没有咋办呢???不慌,想想办法!传值有很多中办法嘛!H5的本地存储(localStorage
、sessionStorage
)等,全局变量,或者写个发布订阅...
我就先图个方便,把状态放到 window
下面了 ^_^
- 首先不管是失焦加粗还是直接选中文字加粗,都要获取通过
selection
和range
这两个对象配合来获取鼠标选中文字,所以把这样方法封装一下为getSelectObj
,返回当前的range
对象和选中的文本信息:(其中的createSelection
是一个考虑了兼容性的创建selection
对象的方法)
getSelectObj = (): object => {
const selObj:Selection = createSelection()
const rangeObj = selObj.getRangeAt(0) // range 被赋予一个 Range 对象
const { collapsed } = rangeObj
return {
rangeObj,
isSelected: collapsed ? false : true,
txt: selObj.toString(),
}
}
-
在 content 组件中定义并注册编辑框的失焦事件,他所做的就是获取当前选中状态,然后把它保存到 window
-
在 toolbar 组件中的 funcBtnEvent 做一些改变:
- 如果选中文字,立即点加粗,就直接取当前状态,继而完成加粗功能
- 如果是失焦状态下点击了加粗,那就要从全局变量 window 下获取刚刚选中的状态,从其中的
range
对象中获取startOffset
和endOffset
,然后利用selection
的addRange
将状态自动选取,继而完成加粗功能,核心代码如下:
const win: any = window const { startOffset, endOffset } = win.xxxx.rangeObj const contentElem = document.getElementById('editContentIdName') as Element const textNode = contentElem.firstChild as Node const selection:Selection = createSelection() const rangeObj:Range = new Range() rangeObj.setStart(textNode, startOffset) rangeObj.setEnd(textNode, endOffset) selection.removeAllRanges() // 所有内容变为非选取状态 selection.addRange(rangeObj) // 然后自动选取某个区域
-
一点小总结:遇事不要慌,完全没有思路的时候,去看看博客,官网的 API 说明,可能会有点想法,慢慢地就上道了!
-
其实还是有 bug,接着完善吧 ..... 代码仓库