如何获取选中文字开头或者结尾的绝对定位

比如你选中了一段文字,需要在选中文字的前面或后面显示一个图标供用户操作,如下图
在这里插入图片描述
你选中的文本可以通过window.getSelection去获取,但它可能是一个text节点,你需要通过获取它的parent节点,但如果你选中的只是这个parent节点的一段文字,定位会不准确。
tips:关于如何实现上面的小冒泡,可以参考这篇地址的如何实现冒泡聊天框。

获取选中文字开头绝对定位

这时候可以通过window.getSelection().getRange(0)其中的inserNode函数往选中文字的前面插入一个空的行内标签,然后通过getBoundingClientRect函数获取该节点相对于浏览器的位置,然后通过绝对定位减去你的气泡提示框的高度去实现定位到选中文字上方。
相关代码如下:

handleMouseup() {
      const sel = window.getSelection()
      const range = sel.getRangeAt(0)
      // 选中文本
      let text = range.toString()
      // 提示气泡框
      const tip = document.getElementById('tip')
      if (!text) {
        tip.style.display = 'none'
        tip.style.top = '-99px'
        tip.style.left = '-99px'
      } else {
        tip.style.display = 'block'
        const span = document.createElement('span')
        range.insertNode(span)
        // 计算绝对定位
        const pos = span.getBoundingClientRect()
        tip.style.top = pos.top - 29/* 提示气泡框的高度 */ + 'px'
        tip.style.left = pos.left + 'px'
        span.remove()
      }
    }

获取选中文字结尾绝对定位

由于range对象没有在选中文本结尾插入节点的函数,需要比和上面多两步操作:
①把选中节点折叠到结尾,在插入定位节点;
②重新选中文本。
另外,由于addRange兼容问题,需要换成setEndsetStart函数来实现选中
相关代码如下:

handleMouseup() {
      const sel = window.getSelection()
      const range = sel.getRangeAt(0)
      // 选中文本
      let text = range.toString()
      // 提示气泡框
      const tip = document.getElementById('tip')
      if (!text) {
        tip.style.display = 'none'
        tip.style.top = '-99px'
        tip.style.left = '-99px'
      } else {
        tip.style.display = 'block'
        // 定位到结尾
        let copyRange = range.cloneRange()
	    sel.addRange(copyRange)
	    range.collapse()
        const span = document.createElement('span')
        range.insertNode(span)
        // 计算绝对定位
        const pos = span.getBoundingClientRect()
        tip.style.top = pos.top - 29/* 提示气泡框的高度 */ + 'px'
        tip.style.left = pos.left + 'px'
        span.remove()
        // 重新选中
        range.setEnd(copyRange.endContainer, copyRange.endOffset)
	    range.setStart(copyRange.startContainer, copyRange.startOffset)
      }
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值