clipboard.js在移动端复制失败的解决方法


Posted in Javascript onJune 13, 2018

1.前沿

一句话介绍下clipboard.js:实现了纯 JavaScript (无 Flash)的浏览器内容复制到系统剪贴板的功能。

在项目中使用clipboard.js插件去实现点击按钮,复制一段网址到剪切板的功能。功能做好后,一开始无论这pc端还是移动端都能正常使用。突然某一天测出了一个bug:移动端复制失败,pc端是ok的。简直一脸懵逼。。。

遇到这个bug,我第一个思考到的是,这是个常用的插件,网上应该有现成的解决方法。网友分享的方法是:把绑定data-clipboard-target属性的按钮标签从div换成button。亲测后,不起效果,可能不是一个原因导致的。通过摸索,找到了bug的原因和可解决方案。我相信,在移动端的项目中使用到clipboard插件,有很大的概率会踩到这个坑,

下面就讲讲解决这个bug的历程。

2、透过表象思考

思考:为什么随着项目的进行,复制功能会失效?我的猜想是:可能是全局禁用了一些默认事件,导致了clipboad.js内部实现复制功能与禁用的默认事件冲突,所以才复制失败。按这个猜想去排查的两个思路:

1、去看clipboard的源码了,找到复制功能的具体实现原理,与哪些事件和默认事件有关联,再去寻找冲突点。

2、业务代码中去排查,哪里做了全局事件的配置,这些配置一个个排查,找出影响了clipboad复制功能的配置。

第一种思路相对牛皮,学习了clipboard原理也是极好的。第二种,是比较笨拙的方法,但是有时候是比较有效的,有可能在少量的试验中就找到了bug点。但是经常是找不出来的,所以只可花少量的时间去试验第二种方法。其实,这里还有第三种思路,就是换一种方式去实现复制功能,可能新的实现方式不受影响,可兼容各平台。clipboard轮子已经造好了,就是为了解决复制功能兼容性为目标诞生的。毕竟还是要相信轮子的实力。通读文档,有两种方式去实现复制功能。

1、我使用的是方法1: html属性绑定。

如下:

<!-- Target -->
<textarea id="bar">Mussum ipsum cacilds...</textarea>

<!-- Trigger -->
<button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">
 Cut to clipboard
</button>

这个就是出现上述bug所使用的方法。

2、改成了文档说明的另外一种实现方法2: js配置参数。如下:

new ClipboardJS('.btn', {
 text: function(trigger) {
  return trigger.getAttribute('aria-label'); // 返回需要复制的内容
 }
});

改成方法2后,成功解决了移动端复制失败的问题。到此为止,若不深究,bug已经被解决,任务完成。

3、寻找原因

可以说,“投机取巧”,花最小的代价,解决了bug。问题虽然解决了,但心有不甘,想找出bug出现的原因。回头认真看了下官方文档,在对方法的描述中,看到这么一段话:

clipboard.js在移动端复制失败的解决方法

大意就是:复制或者剪切操作之后会选中对象,这个对象会通过触发一些cases(事件)去捕获和反馈信息。

重点就是:第一行中的“what has been selected after a copy/cut operation”这句话。根据描述,复制后的对象是被选中状态(selected)的。

然后我立马想到一个事情。在我的项目中,之前有一个同事为了实现长按不选中文本的功能,把长按选中文本的功能全局禁用了。。。。。用的方法是以下css

// 禁止选中html,body{
 user-select: none;
 -moz-user-select: none;
 -webkit-user-select: none;
 -webkit-touch-callout: none;
 -webkit-text-size-adjust: none;
 -webkit-tap-highlight-color: transparent;
 -webkit-user-select: none;
}

找到疑点,通过试验,确实是这个段css导致方法1在移动端复制功能失败。(为什么pc端不失效,移动端失效,这归属于兼容吧,具体原因还不懂。。。)

再回头思考,方法1方法2的区别。可大胆推测:方法1,受css:user-select的影响,应该跟内部实现原理有关。方法2,在new生成实例的时候传入text参数,通过js返回复制内容,所以不受css:user-select的影响。一切推测和表象,达成高度切合。到这里,我只能说,这只是一个强有力的推测。而这个推测是否完全成立,还得研究clipboard.js源码的实现原理,才能真正判断。

问题点找到,解决方案也有了。此bug暂告一个段落!!

舒服(放松脸)。。。。。

4、总结:

1、解决问题的思路有很多。按照逻辑思维,一般是根据问题的表象去分析问题,得出几种思路后,再去验证,最终解决问题。但有时候先不纠结于问题的表象和原因,条条大路通罗马,换一种方式去实现功能,也不错。不管哪种方式去解决,都有不一样的付出和收获。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
JS实现日期加减的方法
Nov 29 Javascript
node.js中的fs.symlink方法使用说明
Dec 15 Javascript
jQuery+jRange实现滑动选取数值范围特效
Mar 14 Javascript
JS使用ajax从xml文件动态获取数据显示的方法
Mar 24 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
Jun 06 Javascript
jQuery图片拖动组件Dropzone用法示例
Jan 17 Javascript
vue-router路由懒加载的实现(解决vue项目首次加载慢)
Aug 28 Javascript
利用React Router4实现的服务端直出渲染(SSR)
Jan 07 Javascript
vue-cli3 取消eslint校验代码的解决办法
Jan 16 Javascript
JavaScript Tab菜单实现过程解析
May 13 Javascript
如何基于viewport vm适配移动端页面
Nov 13 Javascript
vue组件中节流函数的失效的原因和解决方法
Dec 02 Vue.js
ES6与CommonJS中的模块处理的区别
Jun 13 #Javascript
浅谈webpack 构建性能优化策略小结
Jun 13 #Javascript
详解webpack运行Babel教程
Jun 13 #Javascript
Babel 入门教程学习笔记
Jun 13 #Javascript
Vue中在新窗口打开页面及Vue-router的使用
Jun 13 #Javascript
微信小程序支付功能 php后台对接完整代码分享
Jun 12 #Javascript
js replace 全局替换的操作方法
Jun 12 #Javascript
You might like
关于PHP5 Session生命周期介绍
2010/03/02 PHP
Linux下编译redis和phpredis的方法
2016/04/07 PHP
浅谈PHP正则中的捕获组与非捕获组
2016/07/18 PHP
jtable列中自定义button示例代码
2013/11/21 Javascript
javascript中兼容主流浏览器的动态生成iframe方法
2014/05/05 Javascript
JavaScript中的值类型详细介绍
2014/12/29 Javascript
js实现点击图片将图片地址复制到粘贴板的方法
2015/02/16 Javascript
浅析如何利用angular结合translate为项目实现国际化
2016/12/08 Javascript
jQuery读取XML文件的方法示例
2017/02/03 Javascript
AngularJS 支付倒计时功能实现思路
2017/06/05 Javascript
Three.js加载外部模型的教程详解
2017/11/10 Javascript
浅入深出Vue之自动化路由
2019/08/06 Javascript
微信小程序以ssm做后台开发的实现示例
2020/04/08 Javascript
JQuery通过键盘控制键盘按下与松开触发事件
2020/08/07 jQuery
javascript实现雪花飘落效果
2020/08/19 Javascript
python操作xml文件示例
2014/04/07 Python
Python pickle模块用法实例
2015/04/14 Python
python基于itchat实现微信群消息同步机器人
2017/02/27 Python
python利用MethodType绑定方法到类示例代码
2017/08/27 Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
2018/01/04 Python
Python简单实现查找一个字符串中最长不重复子串的方法
2018/03/26 Python
查看django版本的方法分享
2018/05/14 Python
Python中使用socks5设置全局代理的方法示例
2020/04/15 Python
Python 如何操作 SQLite 数据库
2020/08/17 Python
全球最大的网上自行车商店:Chain Reaction Cycles
2016/12/02 全球购物
STRATHBERRY苏贝瑞包包官网:西班牙高级工匠手工打造
2020/11/10 全球购物
班级入场式解说词
2014/02/01 职场文书
业务总经理岗位职责
2014/02/03 职场文书
《乞巧》教学反思
2014/02/27 职场文书
培训讲师岗位职责
2014/04/13 职场文书
车辆年审委托书范本
2014/09/18 职场文书
2015年施工员工作总结范文
2015/04/20 职场文书
机关干部作风整顿心得体会
2016/01/22 职场文书
MySQL系列之十五 MySQL常用配置和性能压力测试
2021/07/02 MySQL
SQL实现LeetCode(197.上升温度)
2021/08/07 MySQL
Mysql 文件配置解析介绍
2022/05/06 MySQL