说在前面
- 浏览器版本:Microsoft Edge 版本 103.0.1264.44
- vue版本:3.2.37
- bootstrap版本:v5.1.3
- jquery版本:v3.6.0
场景
- 在处理服务器发来的数据时,有时需要查看某些
unix时间戳
对应的时间;但是并不清楚哪些字段是时间戳 - 这个时候想要让用户选中就可以进行转换,如下图
实现方式
window.getSelection方法
-
该方法会返回一个描述用户选择文本的对象
-
通过该方法可以进一步获取用户所选的文本所在页面元素,以及对应的位置信息
const selection = window.getSelection() // 获取用户选择对象 if (!selection) { return } if (selection.rangeCount <= 0) { // 如果用户选择范围为0 返回; return // 在用户点击时也会产生对象,此时rangeCount为0 } const range = selection.getRangeAt(0) // 获取第一个选取区域 const rect = range.getBoundingClientRect() // 转换 if (!rect) { return } if (rect.width <= 0) { return } const wholeText = range.startContainer.wholeText // 获取选中的整个文本 const str = wholeText.slice(range.startOffset, range.endOffset) // 切割为实际选中的内容
-
之后我们可以使用这些数据进行进一步的处理,比如添加一个
div
textDiv = document.createElement('div') textDiv.class = 'rect' // textDiv.style.border = '0px solid black' textDiv.style.position = 'fixed' textDiv.style.top = rect.top + 'px' textDiv.style.left = rect.left + 'px' textDiv.style.height = rect.height + 'px' textDiv.style.width = rect.width + 'px' document.body.appendChild(textDiv); // finally append
动态添加bootstrap.Tooltip
- 有了上述数据之后,我们就可以自行添加自己想要的东西了,这里我就加了个
Tooltip
用于转换时间 - 由于没找到什么好的动态添加
Bootstrap Tooltip
的方式,所以我使用了一个比较傻的方式textDiv = document.createElement('div') textDiv.class = 'rect' textDiv.style.position = 'fixed' textDiv.style.top = rect.top + 'px' textDiv.style.left = rect.left + 'px' textDiv.style.height = rect.height + 'px' textDiv.style.width = rect.width + 'px' $(textDiv).attr({ // 添加tooltip所需要的attr "data-bs-toggle": "popover", "title": tm }) document.body.appendChild(textDiv) if (popOver) { // 先销毁原先的 popOver.dispose() } popOver = bootstrap.Tooltip.getOrCreateInstance(textDiv, { trigger: 'focus' // 构造tooltip }) popOver.show() // 显示
完整代码
var popOver = null
var textDiv = null
const onTextSelected = () => {
if (popOver) {
popOver.hide()
}
if (textDiv && textDiv.parentNode) {
textDiv.parentNode.removeChild(textDiv);
}
const selection = window.getSelection()
if (!selection) {
return
}
if (selection.rangeCount <= 0) {
return
}
const range = selection.getRangeAt(0)
if (!range) {
return
}
const rect = range.getBoundingClientRect()
if (!rect) {
return
}
if (rect.width <= 0) {
return
}
const wholeText = range.startContainer.wholeText
if (!wholeText) {
return
}
if (wholeText && wholeText.length <= 0) {
return
}
const str = wholeText.slice(range.startOffset, range.endOffset)
const tm = parseTime(str)
if (!tm) {
return
}
if (tm.length > 0) {
textDiv = document.createElement('div')
textDiv.class = 'rect'
// textDiv.style.border = '0px solid black'
textDiv.style.position = 'fixed'
textDiv.style.top = rect.top + 'px'
textDiv.style.left = rect.left + 'px'
textDiv.style.height = rect.height + 'px'
textDiv.style.width = rect.width + 'px'
$(textDiv).attr({
"data-bs-toggle": "popover",
"title": tm
})
document.body.appendChild(textDiv)
if (popOver) {
popOver.dispose()
}
popOver = bootstrap.Tooltip.getOrCreateInstance(textDiv, {
trigger: 'focus'
})
popOver.show()
}
}
window.onmouseup = onTextSelected