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

前言

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

浏览器选中文本

实现 选中功能效果描述就是左键选中文本,松开出现功能按钮,并且要获取到选中的文本。首先我们来实现功能按钮。 ## 功能按钮 功能按钮只有在选中文本后出现,我们可以通过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事件的区别,如果元素本身很简单,这个功能做起来会更加简便。

相关推荐
一个处女座的程序猿O(∩_∩)O4 分钟前
完成第一个 Vue3.2 项目后,这是我的技术总结
前端·vue.js
mubeibeinv5 分钟前
项目搭建+图片(添加+图片)
java·服务器·前端
逆旅行天涯11 分钟前
【Threejs】从零开始(六)--GUI调试开发3D效果
前端·javascript·3d
m0_7482552632 分钟前
easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层
前端·excel
web147862107231 小时前
C# .Net Web 路由相关配置
前端·c#·.net
m0_748247801 小时前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖1 小时前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案11 小时前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_748254881 小时前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.2 小时前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps