当前位置: 首页 > news >正文

前端技术之---复制文本

仅供参考

文章目录

  • 一、引言
  • 二、方法一:创建隐藏DOM元素
  • 三、方法二:使用现代浏览器的 Clipboard API
  • 四、封装成工具
  • 五、自定义指令


一、引言

在这里插入图片描述

看到这个图标,大家应该都很熟悉,往往放在某行文本旁边,点击即可复制文本内容,这篇文章将仔细说明如何实现“复制”的功能

上面说到是点击之后实现了复制,那么自然而然地可以想到使用 el-button 按钮,里面装着这个图标,点击图标实际上是点击按钮,触发 click 事件,也就是执行了某个函数,实现了复制,可以看出复制的本质是某个函数的执行


二、方法一:创建隐藏DOM元素

<template><div class="mt-96 flex justify-center gap-4 items-center"><p>{{ content }}</p><ElButton type="primary" @click="copy(content)">复制按钮</ElButton></div>
</template><script setup>
import { ref } from "vue";
import { ElMessage } from "element-plus";const content = ref("要复制的内容");const copy = (text) => {return new Promise((resolve, reject) => {try {const input = document.createElement("textarea");input.setAttribute("readonly", "readonly");input.value = text;document.body.appendChild(input);input.select();if (document.execCommand("copy")) document.execCommand("copy");document.body.removeChild(input);ElMessage.success("复制成功");resolve(text);} catch (error) {ElMessage.error("复制失败");reject(error);}});
};
</script>

实现的效果:
点击复制按钮后,弹出成功提示框,粘贴出的内容就是复制的文本
在这里插入图片描述

代码解析:
1、为什么要返回一个Promise对象:目的是将其封装为异步操作,复制成功时通过 resolve(text) 返回结果,发生错误时通过 reject(error) 抛出异常;如果复制后还有后续操作,可以通过 .then(text => {})、.catch(error => {})做进一步处理

2、document.createElement(“textarea”) 创建一个文本框(可以理解为输入框,type 为 textarea),但是这个文本框是隐藏起来的,无法看到

3、input 是 DOM 对象,也具有方法;setAttribute(“readonly”, “readonly”) 方法使其只读,避免用户编辑

4、input.value = text 将需要复制的内容赋值给文本框

5、input.select() 选中文本框中的所有内容

6、document.execCommand(“copy”) 调用浏览器的复制命令,将选中的内容复制到剪贴板;这一步才真正实现了复制;为什么需要做一个判断呢?document.execCommand 函数的返回值为布尔类型,true 表示复制成功,false 表示复制失败,但是早期部分浏览器即使复制成功也会返回 false,所以判断的目的是为了兼容

7、document.body.removeChild(input) 移除临时创建的文本框

这个方法很好理解,但是并不推荐
在这里插入图片描述

三、方法二:使用现代浏览器的 Clipboard API

<template><div style="display: flex; gap: 10px; align-items: center;"><p>{{ content }}</p ><ElButton @click="copy(content)">点击复制</ElButton></div>
</template><!-- <script setup>
import { ElButton, ElMessage } from 'element-plus';
import {ref} from 'vue'const content = ref('要复制的内容')const copy = async(text) => {try {// 写入文本到剪贴板await navigator.clipboard.writeText(text);ElMessage.success('文本复制成功')} catch (error) {ElMessage.error('复制失败')}
}
</script> -->

什么是Clipboard API
Clipboard API 是一组用于访问和操作系统剪贴板的 Web API,允许网页读取和写入剪贴板内容(如文本、图像等),提供了比传统 document.execCommand() 方法更现代、更安全的剪贴板操作方式
1、写入内容到剪贴板:通过 writeText() 写入文本,write() 写入更复杂的数据(如带格式文本、图像等)。
2、从剪贴板读取内容:通过 readText() 读取文本,read() 读取多种格式的内容
3、所有方法均返回 Promise,需配合 async/await 或 .then() 使用

四、封装成工具

从上面的代码可以看出,每个函数都只是对接收的参数做操作,并没有用到组件中其他的内容,因此可以统一写到一个 JS 文件中,封装成工具,暴露出去,想要使用时通过 import 引入即可,避免在多个组件中都写入相同的代码

1、在src 文件夹下创建 utils 文件夹,专门用于存放工具

在这里插入图片描述

2、在 utils 文件夹中创建 copy.js 文件,写入函数

export function copyToClip(text) {return new Promise((resolve, reject) => {try {const input = document.createElement("textarea");input.setAttribute("readonly", "readonly");input.value = text;document.body.appendChild(input);input.select();if (document.execCommand("copy")) document.execCommand("copy");document.body.removeChild(input);resolve(text);} catch (error) {reject(error);}});
}

必须通过 export 将函数暴露出去,否则其他组件无法拿到

不要在工具函数中使用 ElMessage,在组件中调用工具函数后再通过 async/await 后续操作调用 ElMessage

3、在组件中引入并使用工具

<template><div style="margin-top: 400px; display: flex; gap: 10px; align-items: center; justify-content: center;"><p>{{ content }}</p><ElButton type="primary" @click="copyToClip(content)">点击复制</ElButton></div>
</template><script setup>
import {ref} from 'vue'
import { copyToClip } from './utils/copy';const content = ref('要复制的内容')
</script>

可以明显看出,不用在每个组件中重复的写函数,通过引入函数名进行调用即可,大大减少代码量

五、自定义指令

封装成工具后,每次使用都要 import 还是有点麻烦,改造成自定义指令会更加简洁

首先,自定义指令是什么?
1、Vue 本身提供了 v-model、v-show 等内置指令,是固定的写法;而自定义指令可以随便更改,比如我要使用一个复制的自定义指令,可以是 v-copy,也可以是 v-copyText,由自己设定

2、自定义指令允许将重复的 DOM 操作(如样式修改、事件绑定、动画效果等)封装为可复用的模块,避免在组件中重复编写代码。可以简单的理解为,自定义指令的功能就是函数的功能

书写复制的自定义指令:

import { copyToClip } from '@/utils/copy'const handler = (el: any, binding: any) => {el._copyText = binding.valueif (!el._copyHandler) {el._copyHandler = function (event: Event) {event.stopPropagation() // 阻止事件冒泡到父级copyToClip(this._copyText).then(() => {ElMessage.success(window.$t('common.copied'))})}}el.removeEventListener('click', el._copyHandler)el.addEventListener('click', el._copyHandler)
}
export default {mounted: handler,updated: handler,unmounted: (el: any) => {el.removeEventListener('click', el._copyHandler)}
}

代码解析:
1、函数 handler 中的两个形参,el:给哪个 DOM 元素添加了该自定义指令,那么 el 就是该 DOM 对象;binding:DOM 元素的绑定值,在复制的自定义指令中,binding 得到的就是将要复制的内容

2、el._copyText = binding.value 将被复制的内容赋值给 _copyText

3、el.addEventListener(‘click’, el._copyHandler) 为 DOM 元素添加点击事件,点击事件触发,自动调用 el._copyHandler 函数

4、为什么要对 el._copyHandler 做一个判断:避免重复创建函数;如果没有这个判断,每次 handler 执行都会创建一个 el._copyHandler

5、为什么先移除事件监听,又添加事件监听?因为 handler 可能执行多次,避免添加重复的点击事件

6、export default 导出的是一个对象,mounted、updated 分别是元素挂载到 DOM 后、组件更新后触发 handler 函数

完成这步之后,还不能直接使用自定义指令,需要在 main.js 中全局注册自定义指令

import copy from 从上面的导出app.directive('copy', copy)

前一个 copy 是指令的名字,后一个 copy 是上面 export default 导出的对象

此时,就可以使用自定义指令来完成复制操作了:

<ElButton v-copy="要复制的内容"></ElButton>

该自定义指令的本质是元素挂载后、更新后给元素添加点击事件

http://www.dtcms.com/a/355215.html

相关文章:

  • docker安装kafka、zookeeper详细步骤
  • 【TEC045-KIT】基于复旦微 FMQL45T900 的全国产化 ARM 开发套件
  • COLMAP 和 SFM的关系是什么?
  • 微服务即时通信系统(十三)--- 项目部署
  • 第十七章 Java基础-常用API-System
  • ArkTS 与 TypeScript 的关系及鸿蒙开发常见错误案例
  • Upload Symbols Failed
  • 万字详解架构设计:业务架构、应用架构、数据架构、技术架构、单体、分布式、微服务都是什么?
  • 只用三招,无招重启钉钉
  • Video Ocean 接入 GPT-5
  • GeoScene Maps 开发-核心地图-标记点管理-用户交互弹窗
  • 大白话拆解力扣算法 HOT 100 - 哈希/双指针/滑动窗口
  • Mac Pro M4芯片 安装 VMware Fusion 和 windows
  • Vue Router 路由守卫详解与面试指南
  • 实体门店怎么利用小程序做好分销
  • 目标检测领域基本概念
  • 【Python】QT(PySide2、PyQt5):Qt Designer,VS Code使用designer,可能的报错
  • 发那科机器人弧焊电源气体省气装置
  • esp32c2 at 请问通过HTTPS进行OTA升级的AT命令流程有吗?
  • 专项智能练习(多媒体概述)
  • 如果已经安装了electron的一个版本,再次使用命令npm install electron不指定electron版本时,会下载安装新版本么?
  • VS2022+QT6.7+Multimedia(捕获Windows音频数据,生成实时频谱)
  • Day16_【机器学习建模流程】
  • Python备份实战专栏第2/6篇:30分钟搭建企业级API认证系统,安全性吊打90%的方案
  • R语言贝叶斯方法在生态环境领域中的高阶技术应用
  • Mac 开发环境与配置操作速查表
  • 基于Vue2+elementUi实现树形 横向 合并 table不规则表格
  • 华为S5720S重置密码
  • 前沿技术观察:从AI 时代到量子计算的下一站
  • 智能物联网(AIoT)核心技术落地路径与企业数字化转型适配方案