需求小能手——文字选中功能

前言

最近开发了一个很有意思的需求,鼠标选中文字,然后出现一个按钮,点击按钮完成对应的功能,跟浏览器选中文本搜索的功能类似。本身需求不复杂,但是结合其他条件就有点小麻烦,下面来看一下具体的实现过程。

浏览器选中文本

实现 选中功能效果描述就是左键选中文本,松开出现功能按钮,并且要获取到选中的文本。首先我们来实现功能按钮。 ## 功能按钮 功能按钮只有在选中文本后出现,我们可以通过css中的display属性获取v-if/show进行控制,重点是事件跟位置。 - 事件:选中文本会有松开动作,我们很容易想到用mouseup去触发。但是如果元素本身有click事件就会有问题,当鼠标松开时mouseup与click都会触发,我们是希望这两个事件互相不影响。思考了一会决定用鼠标按下松开间隔时间区分,点击一般要比选中的时间短。我们去掉click,绑定mousedown与mouseup,当鼠标按下时记录当前时间,松开时获取当前时间与之前的时间进行对比。

js 复制代码
handleMouseDown() {
// 当前时间
this.downTime = new Date().getTime()
},
handleMouseUp() {
const nowTime = new Date().getTime()
if (nowTime - this.downTime > 100) {
// mouseup逻辑
} else {
// click逻辑
}
},

判断条件的时长可以进行微调。

  • 位置:结合浏览器选中文本效果,当我们松开鼠标时,按钮就应该在鼠标附近出现,也就是说按钮的位置是相对于鼠标出现的位置,相对位置就很容易联想到absolute相对定位,所以我们将按钮position设置为absolute,接下来就是通过top、left确定按钮位置。top、left肯定是通过鼠标的位置获取的,如果我们的文本自身有div包裹,为了更加美观,我们可以获取div的宽高,然后用当前鼠标位置减去div宽、高,最后根据实际效果进行微调。通过以上分析,我们定义三个变量:
    buttonShow ------------ 控制按钮显示、隐藏
    buttonLeft/Top ------------ 控制按钮位置


getBoundingClientRect方法可以获取元素width、height、top等属性值,使用起来非常方便。我们通过style让button动态绑定这些属性。

js 复制代码
<el-button
v-show="buttonShow"
:style="{ position: 'absolute', top: buttonTop, left: buttonLeft }"
@click="handleSearch"
>搜索</el-button>

注意,这里我们用v-show去控制按钮的显示隐藏,一来按钮操作会相对频繁,二来方便我们接下来的优化。

需求优化

到此我们只要点击按钮触发功能逻辑,同时让按钮消失就算完成了该需求。但是目前触发按钮消失的方式很单一,我又研究了下浏览器的相关功能,发现以下两种也能触发按钮消失:

  1. 滚动条滚动。
  2. 鼠标移动一定距离,渐变消失。 所以为了这个需求用起来更加丝滑,我们也加上这两个功能。滚动条滚动这个非常简单,监听滚动事件,当滚动条滚动时buttonShow为false。
js 复制代码
window.addEventListener('scroll', () => {
if (this.buttonShow) {
this.buttonShow = false
}
})

重点是第二个鼠标移动一定距离渐变消失,首先我们来确认这个移动范围,该移动范围可以当作移动面积,具体的形状我们可以自定义,比如正方形、圆等。这里我们选择圆,当作范围,直接用圆的方程公式去做判断,js中通过Math.pow去表示平方。

注意坐标中的1一般情况下跟1px是对等的,都是物理像素。上面我们提到了消失是渐变消失,那么我们也给按钮消失加上渐变动画,这里我们使用vue中的Transition组件,这也是我们用v-show控制的原因。

js 复制代码
<Transition name="fade">
<el-button>...
</Transition>

注意css中的前缀跟name要匹配,最后我们通过window.getSelection().toString()拿到选中文本,执行业务逻辑。

总结

以上就是文字选中功能,重点是click与mouseup事件的区别,如果元素本身很简单,这个功能做起来会更加简便。

相关推荐
why技术几秒前
AI Coding开始进入第四个时代,我还没上车呢!
前端·人工智能·后端
大家的林语冰1 小时前
CSS 已死?DOM 性能黑洞!Pretext 排版革命让你在文本间跳舞,没有 DOM 也能纵享丝滑~
前端·javascript·css
vipbic1 小时前
我也该升级了,陪伴了我7年的博客
前端
Lee川1 小时前
RAG 实战:从一篇掘金文章出发,拆解检索增强生成的全链路
前端·人工智能·后端
Lee川1 小时前
MCP 高德地图实战:当 AI 学会使用工具,一个协议如何重塑大模型的行动边界
前端·人工智能·后端
ZC跨境爬虫2 小时前
跟着 MDN 学CSS day_14:(尺寸调整技能测试与实战解析)
前端·css·ui·html·tensorflow
kyriewen2 小时前
用魔法打败魔法:我让AI替我去面试前端岗,AI面试官给我打了92分,还发了offer
前端·javascript·面试
IT_陈寒2 小时前
Redis批量删除踩了坑,原来DEL命令不是万能的
前端·人工智能·后端
lichenyang4532 小时前
鸿蒙聊天 Demo 练习 06:AI 思考气泡与 MVVM + Controller 结构重构
前端
Lkstar3 小时前
Vue keep-alive 原理全解:LRU 缓存策略、源码级理解
前端·vue.js·面试