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

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

正常来说一键复制只需要在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. '@JvmDefault' is only supported since JVM target 1.8. Recompile with '-jvm-ta

    Java 1.8加入了接口默认实现的方式. 那么在kotlin中如何使用呢? 可以在方法上加注解@JvmDefault 但直接加上后会编译会碰到一些错误提示.下面是解决方法. 问题 Logcat 提示 ...

  2. Java高并发-无锁

    一.无锁类的原理 1.1 CAS CAS算法的过程是这样:它包含3个参数CAS(V,E,N).V表示要更新的变量,E表示预期值,N表示新值.仅当V值等于E值时,才会将V的值设为N,如果V值和E值不同, ...

  3. Es6语法+v-on参数相关+vue虚拟dom

    Es6的语法 Es5:if和for 都没有块级作用域,函数function有作用域. Es6:加入let使得if和for有作用域 .建议: 在Es6中优先使用const,只有需要改变某一个标识符的时候 ...

  4. 题解 P7075 [CSP-S2020] 儒略日

    当时考场上因为这个炸掉,一年后回来复仇. 这里提供一个与大多数人不一样的做法. 首先考虑一个简单一些的问题,怎么应付单个询问? 不难想到,我们对于一个日期,让他从 \(-4713\) 年 \(1\) ...

  5. 用HMS Core地图服务自定义地图样式,给你的应用制作专属个性化地图

    不同行业的开发者对地图样式的展示需求差异很大.例如,物流类应用希望地图样式简洁一些,重点突出城市分布和快递路径:AR游戏类应用中的地图色彩需要和游戏UI适配,做的更酷炫一些:景区导览应用中的地图样式要 ...

  6. static关键字——JavaSE基础

    static关键字 由于static跟随类被加载,因此静态代码块.构造方法.匿名代码块的执行顺序为静态代码块→匿名代码块→构造方法 public class Demo01 { public stati ...

  7. Dcoker镜像管理与容器应用

    Dcoker镜像管理与容器应用 docker基于镜像创建容器 相同版本的镜像只允许存在一个 同一个镜像可以创建多个容器 镜像管理 [root@localhost ~]# docker pull cen ...

  8. 整数分解、for循环阶乘

    整数分解 整数分解是什么呢??我们可以这样理解 我们写一个 3位数求出它的个位十位和百位 . 那么我们来写一个小的测试来看一下! public static void main(String[] ar ...

  9. 合宙AIR105(二): 时钟设置和延迟函数

    目录 合宙AIR105(一): Keil MDK开发环境, DAP-Link 烧录和调试 合宙AIR105(二): 时钟设置和延迟函数 Air105 的时钟 高频振荡源 芯片支持使用内部振荡源, 或使 ...

  10. 教你如何用网页开发APP

    用到的工具: HBuilderX app开发版1.首先你得网站必须是上线的,然后明确这一点后,点击打开HBuilderX.在文件里找到新建项目,选择wap2App,将下面信息填写完整,然后创建. 2. ...