今天接到了一个新的需求,要求我们对表单中的某一个字段进行复制,这个表单是不可选的,拿到需求的时候有点懵,不清楚下手点在哪,后来网上找了找,终于有了点眉目,感觉网上有些是实现不了的,特地在这里记录下进行总结

实现复制功能,因为需求没有明确提出是要一键复制,还是长摁复制,所以把两种都讲了吧

正常来说一键复制只需要在onclick事件即可,但是因为我的表单是disabled状态的,他没办法执行onclick

所以走了捷径,直接用 ontouchstart 如果要长摁,就加入一个定时器就好了

直接上代码吧

  const copy = document.getElementById('text-surveyPreRequirementCode')

  if (copy) {
copy.ontouchstart = function () {
CopyId(copy)//此处可以加入定时器来设置他是点击事件还是长摁事件,如你们的表单不是disabled,就直接用onclick
}
} const CopyId = async (copyDOM: any) => {
console.log(copyDOM.textContent);
try {
const clipboardObj = navigator.clipboard;
await clipboardObj.writeText(copyDOM.textContent)
Toast.info('复制成功')
} catch (error) {
Toast.info(`错误,${error}`)
}
}

看了网上的博客,大家的做法大多是用

document.execCommand("copy") 

贴一下别人的代码

CopyOrderSerialId() {
var system = navigator.userAgent;//获取系统信息
//苹果
if (system.match(/(iPhone|iPod|iPad);?/i)) {
window.getSelection().removeAllRanges(); //将页面所有的文本区域都从选区中移除
var copyDOM = document.getElementById("orderId-copy"); //要复制文字的节点
var range = document.createRange();
// 选中需要复制的节点
range.selectNode(copyDOM);
// 执行选中元素
window.getSelection().addRange(range);
// 执行 copy 操作
var successful = document.execCommand('copy');
try {
var msg = successful ? '成功' : '失败';
this.$toast("复制"+msg );
} catch (err) {
// this.$toast("复制失败,请从事");
}
// 移除选中的元素
window.getSelection().removeAllRanges();
}
// 安卓
if (system.indexOf('Android') > -1) {
var orderUrl = this.orderData.OrderSerialId;// 获取订单号
var newInput = document.createElement("input");// 这里的逻辑就是新建立一个input标签,
newInput.value = orderUrl +'';// 把订单号设置为input的value值
document.body.appendChild(newInput);// 把input添加到body中
newInput.select(); // select 选中input里面的所有文本内容
document.execCommand("Copy"); // 执行浏览器复制命令
document.body.removeChild(newInput); // 最近需要销毁
this.$toast("复制成功");//调用引入的轻提示插件告诉用户复制成功
}
},
————————————————
版权声明:本文为CSDN博主「无所事事的小老弟」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fengkui347235/article/details/103906709

在用 document.execCommand("Copy") 会有一个很大的坑:他没办法异步!!!

无法异步,意味着你ajax请求的数据是无法复制的,我们都知道ajax是异步请求的,而document.execCommand("Copy")没办法异步执行,因此无法及时的复制文本

document.execCommand()这个api只能在真正的用户操作之后才能被触发,是为了安全考虑。原理大致是这样的,当用户操作之后,chrome会将当前作用域下的userAction变量置为True(编的变量名),然后执行execCommand时就会去读取这个变量,当为True的时候才可以执行。

因为ajax基本都是异步请求,而异步请求不同于同步请求的地方就在于重新创建了一个作用域去执行回调函数。

所以在重新创建一个作用域之后,之前作用域内的userAction就失效了,当前作用域下的userAction为false,所以复制不成功。

解决办法

  1. 用真正的用户操作去执行execCommand。(可能需要修改交互流程)
  2. 将异步请求改成同步请求。这样做就不会创建新的作用域,execCommand命令依旧在userAction为true的上下文下执行。(当然这种做法也不是很推荐,但为了满足需求只能这样做,只要把xhr.open里的最后一个参数改为false即可满足同步请求)

不过说真的,无法理解,只好另辟蹊径

这是发现了一个新的api(在阮一峰那找到的,感兴趣的建议去看看,链接:http://www.ruanyifeng.com/blog/2021/01/clipboard-api.html)

Clipboard

Clipboard API 是下一代的剪贴板操作方法,比传统的document.execCommand()方法更强大、更合理。

它的所有操作都是异步的,返回 Promise 对象,不会造成页面卡顿。而且,它可以将任意内容(比如图片)放入剪贴板。

navigator.clipboard属性返回 Clipboard 对象,所有操作都通过这个对象进行。

在这里我就只介绍我用的方法吧

Clipboard.writeText()

Clipboard.writeText()方法用于将文本内容写入剪贴板。这样子你就可以粘贴了

使用这个办法,异步的问题就解决了。

但是有一个问题就是他的兼容性有待商榷

欢迎大家多多探讨

H5移动端实现一键复制或长摁复制的更多相关文章

  1. h5页面在ios机上禁止长按复制

    (注意,增加之后需要对input的另外设置,不然输入框无法输入)场景:H5出现一个按钮需要长按几秒展示动画的,如:skcs.net-tactic.com/wap/peace/index,这时就需要用到 ...

  2. 微信小程序——长按复制、一键复制

    wxml: 订单号:<text selectable='true' bindlongtap='copy' >{{OrderModel.OrderNo}}</text><b ...

  3. 让cocos h5里的文字可以在手机上被长按复制

    更改CCBoot.js代码: // Adjust mobile css settings if (cc.sys.isMobile) { var fontStyle = document.createE ...

  4. H5移动端知识点总结

    H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解display:box的布局 理解flex布局 Flex布局兼容知识点总结 回到顶部 移动开 ...

  5. 10天学会phpWeChat——第七天:创建一个自适应PC网站+H5移动端的模块

    本教程基于phpWeChat核心框架1.1.0+版本.下载地址:http://s.phpwechat.com/app_38026ed22fc1a91d92b5d2ef93540f20 通过前面六讲的系 ...

  6. 【转】TextView长按复制实现方法小结

    有这么一个需求,用户在浏览文本信息时希望长按信息就能弹出复制的选项方便保存或者在别的页面使用这些信息.类似的, 就像长按WebView或者EditText的内容就自动弹出复制选项. 这里面主要是2个特 ...

  7. 阻止长按复制页面中的内容;zepto中touch中的应用必须先加载event模块之后;

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 基于SwiperJs的H5/移动端下拉刷新上拉加载更多的效果

    最早时,公司的H5项目中曾用过点击一个"加载更多"的DOM元素来实现分页的功能,后来又用过网上有人写的一个上拉加载更多的插件,那个插件是页面将要滚动到底部时就自动请求数据并插入到页 ...

  9. 旅行app(游记、攻略、私人定制) | 顺便游旅行H5移动端实例

    <顺便游旅行>是一款H5移动端旅行app,提供目的地(国内.国外.周边)搜索.旅游攻略查询.游记分享.私人定制4大模块,类似携程.同程.去哪儿.马蜂窝移动端,只不过顺便游app界面更为简洁 ...

随机推荐

  1. SpringBoot从0到0.7——第四天

    SpringBoot从0到0.7--第四天 今天进行实战开发一个小项目,SpringBoot和Thymeleaf集成的小项目 因为懒得写写前端,直接找的别人的项目在它的的基础上进行配置,进行修改.gi ...

  2. Debouncer防抖代码

    Debouncer类 import java.util.concurrent.*; public class Debouncer { private final ScheduledExecutorSe ...

  3. 用c++语言socket库函数实现服务端客户端聊天室

    客户端 /* * 程序名:client.cpp,此程序用于演示socket的客户端 * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include < ...

  4. Linux下MySQL表名区分大小写

    问题:MySQL一个数据库的表名统一小写,在Windows上安装的MySQL没有问题,但是把数据库部署到Linux上,应用启动的时候报表不存在错误. 解决:修改my.cnf lower_case_ta ...

  5. Spark: 单词计数(Word Count)的MapReduce实现(Java/Python)

    1 导引 我们在博客<Hadoop: 单词计数(Word Count)的MapReduce实现 >中学习了如何用Hadoop-MapReduce实现单词计数,现在我们来看如何用Spark来 ...

  6. Eoapi — 一个可拓展的开源 API 工具

    ​ 在社区中时常会出现"抱怨某商业产品越来越臃肿"的声音,API 工具也是如此.从最早期只做 API 调试的工具,到经过多年的演进后集成全面功能的"庞然大物", ...

  7. Code Forces 1367A Sorting Parts 题解

    (原题链接:CF传送门) 题目背景(我看不懂英文嘤嘤嘤) Sorting Parts You have an array a of length n. You can exactly once sel ...

  8. Puppeteer学习笔记 (2)- Puppeteer的安装

    本文链接:https://www.cnblogs.com/hchengmx/p/11009849.html 1. node的下载安装 由于puppeteer是nodejs的一个库,所以首先需要安装no ...

  9. 陈宏智:字节跳动自研万亿级图数据库ByteGraph及其应用与挑战

    导读: 作为一种基础的数据结构,图数据的应用场景无处不在,如社交.风控.搜广推.生物信息学中的蛋白质分析等.如何高效地对海量的图数据进行存储.查询.计算及分析,是当前业界热门的方向.本文将介绍字节跳动 ...

  10. ABP Framework 5.3.0 版本新增功能和变更说明

    ABP Framework 5.3.0 稳定版已在2022年6月14日正式发布. 以下是本版本的新增功能: "开始"页面提供创建单层项目选项 启动模板提供 PWA 支持 Volo. ...