前端实现复制粘贴功能

在前端开发的世界里,复制粘贴功能就像是那个总是被忽视,却在关键时刻能救你一命的老朋友。我们习惯了用那些古老的魔法咒语(document.execCommand('copy'))来实现这一功能,但时代在进步,技术在更新,是时候告别那些让人头疼的兼容性问题,迎接新时代的剪贴板API了。

旧时代的遗物

在那个遥远的时代,我们为了实现复制粘贴功能:

  1. 不得不创建一个神秘的textarea元素,

  2. 然后让它隐形(通过CSS隐藏)

  3. 给它赋予力量(设置值)

  4. 将它召唤到页面的某个角落,然后通过古老的仪式(调用select方法和execCommand

  5. 最后在一切完成之后,让它消失在历史的长河中(移除元素)。

代码如下:

 // 创建一个临时的 textarea 元素
  const textarea = document.createElement('textarea');
  // 设置 textarea 的内容
  textarea.value = inputElement.value;
  // 防止在页面上显示 textarea
  textarea.setAttribute('readonly', '');
  textarea.style.position = 'absolute';
  textarea.style.left = '-9999px';
  // 将 textarea 添加到页面中
  document.body.appendChild(textarea);
  // 选中 textarea 的内容
  textarea.select();
  // 尝试执行复制操作
  const success = document.execCommand('copy');
  // 移除 textarea 元素
  document.body.removeChild(textarea);
  // 根据复制操作的成功与否给出提示
  if (success) {
    alert('复制成功!');
  } else {
    alert('复制失败,请手动复制。');
  }

这个过程虽然繁琐,但在当时,它是我们唯一的选择。

新时代的使者

随着navigator.clipboard API的诞生,我们终于可以告别那些复杂的仪式。这个API提供了两个强大的方法:writeTextreadTextwriteText方法允许我们异步地将文本写入剪贴板,而readText则可以读取剪贴板中的文本。这两个方法的使用非常简单,只需要几行代码,就可以实现复制和粘贴的功能。

复制功能的实现

const copyText = async (text) => {
  try {
    await navigator.clipboard.writeText(text);
    console.log('复制成功!');
  } catch (err) {
    console.error('无法复制: ', err);
  }
};

粘贴功能的实现

const pasteText = async () => {
  try {
    const text = await navigator.clipboard.readText();
    console.log('粘贴成功: ', text);
  } catch (err) {
    console.error('无法粘贴: ', err);
  }
};

兼容性与挑战

Navigator 这种新 API 都是需要事先授予权限的,而权限是通过 Permissions API 获取的。这时候,我们需要用户明确授权。

虽然新API带来了便利,但它并不是万能的。在某些环境下,比如安卓的 WebView,我们可能会遇到权限问题。

Permissions API MDN

注意 Permissions API 在安卓的 WebView 中是没实现的。很多小伙伴都容易在这里栽跟头

此时,为了兼容,我们可以在代码里加一个Permissions API的判断, 例如:

if (navigator.clipboard && navigator.permissions) { 
    await navigator.clipboard.writeText(val) 
}

结语

随着技术的发展,我们有理由相信,未来会有更多简单、强大、兼容性更好的API出现。但在那之前,让我们拥抱navigator.clipboard,享受它带来的便利,同时也不忘那些曾经陪伴我们度过难关的老方法。毕竟,navigator.clipboard 在一些特别的情况下表现得不那么优秀,我们可以结合二者来实现一个,在各种情况下都通用的“复制粘贴”:

const copyText = async (val) => {
  try {
    // 使用现代 API 尝试复制
    if (navigator.clipboard && navigator.permissions) {
      await navigator.clipboard.writeText(val);
      return; // 如果成功,直接返回
    }

    // 降级方案
   const textArea = document.createElement('textArea') 
   textArea.value = val 
   textArea.style.width = 0 
   textArea.style.position = 'fixed' 
   textArea.style.left = '-999px' 
   textArea.style.top = '10px' 
   textArea.setAttribute('readonly', 'readonly')
   document.body.appendChild(textArea) 
   textArea.select()

    // 尝试执行复制操作
    const success = document.execCommand('copy');
    if (!success) {
      throw new Error('无法复制文本');
    }

    // 清理
    document.body.removeChild(textArea);
  } catch (err) {
    console.error('复制失败:', err);
  }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/454689.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LNMP架构之web服务器实战

LNMP架构 1.nginx部署 systemctl disable --now keepalived.service 关闭keepalived服务,避免冲突 将下载好的nginx软件压缩包直接拖入mobaxterm目录即可 tar zxf nginx-1.23.3.tar.gz cd nginx-1.23.3/ yum install -y gcc pcre-devel openssl-devel #安装依…

LInux系统架构----Nginx模块rewrite的规则与应用场景

LInux系统架构----Nginx模块rewrite的规则与应用场景 一.rewrite跳转实现 Nginx实现跳转通过ngx_http_rewrite_module模块支持URL重写、支持if条件判断,但是不支持else跳转时,循环最多可以执行10次,超过后nginx将返回500错误注:…

0基础使用dockerfile构建容器镜像

目录 一、使用dockerfile构建镜像 1.1、dockerfile指令 1.FROM 2.RUN 3.CMD 4.ENTRYPOINT 5.EXPOSR ​编辑 6.ADD和COPY ​编辑7.volume 8.USER 二、案例1:dockerfile构建httpd镜像 构建一个指定挂载点的httpd镜像 三、案例2:构建tomcat镜…

使用endnote插入引用文献导致word英文和数字变成符号的解决方案

使用endnote插入引用文献导致word英文和数字变成符号的解决方案 如图使用endnote插入引用文献导致word英文和数字变成符号字体Wingdings Wingdings 是一个符号字体系列,它将许多字母渲染成各式各样的符号,用途十分广泛。 **解决方法:**直接通…

【相关问题解答1】bert中文文本摘要代码:import时无法找到包时,几个潜在的原因和解决方法

【相关问题解答1】bert中文文本摘要代码 写在最前面问题1问题描述一些建议import时无法找到包时,几个潜在的原因和解决方法1. 模块或包的命名冲突解决方法: 2. 错误的导入路径解决方法: 3. 第三方库的使用错误解决方法: 4. 包未正…

gpt-4-all模型中转实现

最近才完成这个功能,相信知道这个模型的人,应该已经熟悉了。这是我的中转:openai-api Chatbox配置如下: 模型测试: 1)图片生成 2)文件分析,链接读取:

WPF实时时间显示demo(MVVM)

跟着b站的视频学习做一个界面,它里面的时间不能实时刷新,因此自己研究写一个,同时加深一下自己对MVVM的理解. 运行结果: 实现步骤: 1.界面 界面设计就是放置了一个TextBlock,它的text绑定了ViewModel层里面的公告属性CurrentTime. <Grid><TextBlock Text"{Bindi…

【Vite+Ts】自动按需引入Element-Plus

安装插件 cnpm i -D unplugin-vue-components unplugin-auto-import unplugin-element-plus修改vite.config.ts // vite.config.ts import AutoImport from "unplugin-auto-import/vite"; import Components from "unplugin-vue-components/vite"; impor…

白嫖AWS云服务器,验证、注册指南

背景 不知道你想不想拥有一台属于自己的云服务器呢&#xff0c;拥有一台自己的云服务器可以建站&#xff0c;可以在上面搭建个人博客&#xff0c;今天我就来教大家如何申请亚马逊 AWS 免费云服务器&#xff0c;这个云服务器可以长达12个月的免费。而且到期后可以继续换个账号继…

【Flink SQL】Flink SQL 基础概念:SQL 动态表 连续查询

Flink SQL 基础概念&#xff1a;SQL 动态表 & 连续查询 1.SQL 应用于流处理的思路2.流批处理的异同点及将 SQL 应用于流处理核心解决的问题3.SQL 流处理的输入&#xff1a;输入流映射为 SQL 动态输入表4.SQL 流处理的计算&#xff1a;实时处理底层技术 - SQL 连续查询5.SQL…

Arduino IDE的下载和安装

一、Arduino的介绍 Arduino是一款开源电子原型平台&#xff0c;主要包含两部分&#xff1a;硬件&#xff08;各种型号的Arduino板&#xff09;和软件&#xff08;Arduino IDE&#xff09;。这个平台由意大利的Massimo Banzi、David Cuartielles等人共同开发设计&#xff0c;并于…

OPPO后端二面,凉了!

这篇文章的问题来源于一个读者之前分享的 OPPO 后端凉经&#xff0c;我对比较典型的一些问题进行了分类并给出了详细的参考答案。希望能对正在参加面试的朋友们能够有点帮助&#xff01; Java String 为什么是不可变的? public final class String implements java.io.Seri…

【毕设级项目】基于嵌入式的智能家居控制板(完整工程资料源码)

基于嵌入式的智能家居控制板演示效果 基于嵌入式的智能家居控制板 前言&#xff1a; 随着科技的不断进步&#xff0c;物联网技术得到了突飞猛进的发展。智能家居是物联网技术的典型应用领域之一。智能家居系统将独立家用电器、安防设备连接成一个具有思想的整体&#xff0c;实现…

清华把大模型用于城市规划,回龙观和大红门地区成研究对象

引言&#xff1a;参与式城市规划的新篇章 随着城市化的不断推进&#xff0c;传统的城市规划方法面临着越来越多的挑战。这些方法往往需要大量的时间和人力&#xff0c;且严重依赖于经验丰富的城市规划师。为了应对这些挑战&#xff0c;参与式城市规划应运而生&#xff0c;它强…

汽车IVI中控开发入门及进阶(十四):功能安全

前言: 是时候需要来说一下功能安全了,有没有发现现在很多主机厂、Tier1对芯片等BOM物料有些是有功能安全需求的,那么什么是功能安全呢? 车辆中电子元件数量的增加增加了更多故障的可能性,对驾驶员和乘客的风险更高。这种风险的增加导致汽车行业将功能安全标准作为汽车设计…

C库函数-getopt函数总结学习

1、简介 getopt函数是命令行参数解析函数 1、1命令行组成 Command name 程序文件名 operands 操作对象 option 选项 option argument 选项参数 getopt()函数将传递给mian()函数的argc,argv作为参数&#xff0c;同时接受字符串参数optstring – optstring是由选项Option字母组…

cesiumlab中shp转3dtiles白模效果一

安装cesiumlab 如果没有安装cesiumlab&#xff0c;去官网下载安装一个即可 http://www.cesiumlab.com/cesiumlab.html 效果 步骤 1、准备shp面数据 2、打开cesiumlab软件转换 选择shp面数据 设置高度&#xff0c;如果shp面中有高度字段&#xff0c;可以用高度字段&#xff…

高铁列车员信息宣传向媒体投稿有哪些方法?

作为一名高铁列车工作人员,我肩负着传递高铁精神、展示列车员风采的重要使命。每月,我都要完成单位对外信息宣传的考核任务,通过媒体投稿来发表列车员的信息宣传文章。在这条信息宣传之路上,我经历了从摸着石头过河到智慧投稿的蜕变,其中的心酸与轻松交织,成为了我职业生涯中难…

云原生消息流系统 Apache RocketMQ 在腾讯云的大规模生产实践

导语 随着云计算技术的日益成熟&#xff0c;云原生应用已逐渐成为企业数字化转型的核心驱动力。在这一大背景下&#xff0c;高效、稳定、可扩展的消息流系统显得尤为重要。腾讯云高级开发工程师李伟先生&#xff0c;凭借其深厚的技术功底和丰富的实战经验&#xff0c;为我们带…

基于C++的一种字符串切分方法及示例代码

一、概述 在 Java 和 python 中&#xff0c;都有实现字符串切分的方法&#xff0c; 如split() &#xff0c;使用起来较为方便&#xff0c;但是在标准的 C 中&#xff0c;却没有内置的 split() 方法。 我们可以使用标准库中的一些函数和方法来实现字符串的切分&#xff0c;这里…