蚂蚁老码农——JavaScript复制内容到剪贴板

最近一个活动页面中有一个小需求,用户点击或者长按就可以复制内容到剪贴板,记录一下实现过程和遇到的坑。
常见方法
查了一下万能的Google,现在常见的方法主要是以下两种:

第三方库:clipboard.js
原生方法:document.execCommand()

分别来看看这两种方法是如何使用的。
clipboard.js
这是clipboard的官网:clipboardjs.com/,看起来就是这么的简单。
引用
直接引用: <script src="dist/clipboard.min.js"></script>
包: npm install clipboard --save ,然后 import Clipboard from ‘clipboard‘;
使用
从输入框复制
现在页面上有一个 <input> 标签,我们需要复制其中的内容,我们可以这样做:
<input id="demoInput" value="hello world">
<button class="btn" data-clipboard-target="#demoInput">点我复制</button>
import Clipboard from ‘clipboard‘;
const btnCopy = new Clipboard(‘btn‘);
注意到,在 <button> 标签中添加了一个 data-clipboard-target 属性,它的值是需要复制的 <input> 的 id,顾名思义是从整个标签中复制内容。
直接复制
有的时候,我们并不希望从 <input> 中复制内容,仅仅是直接从变量中取值。如果在 Vue 中我们可以这样做:
<button class="btn" :data-clipboard-text="copyValue">点我复制</button>
import Clipboard from ‘clipboard‘;
const btnCopy = new Clipboard(‘btn‘);
this.copyValue = ‘hello world‘;
事件
有的时候我们需要在复制后做一些事情,这时候就需要回调函数的支持。
在处理函数中加入以下代码:
// 复制成功后执行的回调函数
clipboard.on(‘success‘, function(e) {
console.info(‘Action:‘, e.action); // 动作名称,比如:Action: copy
console.info(‘Text:‘, e.text); // 内容,比如:Text:hello word
console.info(‘Trigger:‘, e.trigger); // 触发元素:比如:<button class="btn" :data-clipboard-text="copyValue">点我复制</button>
e.clearSelection(); // 清除选中内容
});

// 复制失败后执行的回调函数
clipboard.on(‘error‘, function(e) {
console.error(‘Action:‘, e.action);
console.error(‘Trigger:‘, e.trigger);
});
小结
文档中还提到,如果在单页面中使用 clipboard ,为了使得生命周期管理更加的优雅,在使用完之后记得 btn.destroy() 销毁一下。
clipboard 使用起来是不是很简单。但是,就为了一个 copy 功能就使用额外的第三方库是不是不够优雅,这时候该怎么办?那就用原生方法实现呗。
document.execCommand()方法
先看看这个方法在 MDN 上是怎么定义的:

which allows one to run commands to manipulate the contents of the editable region.

意思就是可以允许运行命令来操作可编辑区域的内容,注意,是可编辑区域。
定义

bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

方法返回一个 Boolean 值,表示操作是否成功。

aCommandName :表示命令名称,比如: copy, cut 等(更多命令见命令);
aShowDefaultUI:是否展示用户界面,一般情况下都是 false;
aValueArgument:有些命令需要额外的参数,一般用不到;

兼容性
这个方法在之前的兼容性其实是不太好的,但是好在现在已经基本兼容所有主流浏览器了,在移动端也可以使用。

使用
从输入框复制
现在页面上有一个 <input> 标签,我们想要复制其中的内容,我们可以这样做:
<input id="demoInput" value="hello world">
<button id="btn">点我复制</button>
const btn = document.querySelector(‘#btn‘);
btn.addEventListener(‘click‘, () => {
const input = document.querySelector(‘#demoInput‘);
input.select();
if (document.execCommand(‘copy‘)) {
document.execCommand(‘copy‘);
console.log(‘复制成功‘);
}
})
其它地方复制
有的时候页面上并没有 <input> 标签,我们可能需要从一个 <div> 中复制内容,或者直接复制变量。
还记得在 execCommand() 方法的定义中提到,它只能操作可编辑区域,也就是意味着除了 <input>、<textarea> 这样的输入域以外,是无法使用这个方法的。
这时候我们需要曲线救国。
<button id="btn">点我复制</button>
const btn = document.querySelector(‘#btn‘);
btn.addEventListener(‘click‘,() => {
const input = document.createElement(‘input‘);
document.body.appendChild(input);
input.setAttribute(‘value‘, ‘听说你想复制我‘);
input.select();
if (document.execCommand(‘copy‘)) {
document.execCommand(‘copy‘);
console.log(‘复制成功‘);
}
document.body.removeChild(input);
})
算是曲线救国成功了吧。在使用这个方法时,遇到了几个坑。
遇到的坑
在Chrome下调试的时候,这个方法时完美运行的。然后到了移动端调试的时候,坑就出来了。
对,没错,就是你,ios。。。

点击复制时屏幕下方会出现白屏抖动,仔细看是拉起键盘又瞬间收起
知道了抖动是由于什么产生的就比较好解决了。既然是拉起键盘,那就是聚焦到了输入域,那只要让输入域不可输入就好了,在代码中添加 input.setAttribute(‘readonly‘, ‘readonly‘); 使这个 <input> 是只读的,就不会拉起键盘了。

无法复制
这个问题是由于 input.select() 在ios下并没有选中全部内容,我们需要使用另一个方法来选中内容,这个方法就是 input.setSelectionRange(0, input.value.length);。

完整代码如下:
const btn = document.querySelector(‘#btn‘);
btn.addEventListener(‘click‘,() => {
const input = document.createElement(‘input‘);
input.setAttribute(‘readonly‘, ‘readonly‘);
input.setAttribute(‘value‘, ‘hello world‘);
document.body.appendChild(input);
input.setSelectionRange(0, 9999);
if (document.execCommand(‘copy‘)) {
document.execCommand(‘copy‘);
console.log(‘复制成功‘);
}
document.body.removeChild(input);
})

原文地址:http://blog.51cto.com/13552785/2073506

时间: 2024-09-28 00:15:25

蚂蚁老码农——JavaScript复制内容到剪贴板的相关文章

老码农教你在 StackOverflow 上谈笑风生

作为一个高大上的码农,你肯定用到过 StackOverflow,必须的.会有人否定这个断言么?那他恐怕不是真正的码农,或者说还没入门.StackOverflow 对于码农的重要性,基本就和诸葛亮对刘备的重要性差不多,它上知 Java 下知 MySQL,中间懂得各种算法.只要你拥有与它沟通的技巧,它几乎可以回答你遇到的任何技术问题. 不过,很多码农对它的体验也就仅限于此了.查询一下,找到问题,然后把里边的代码复制粘贴到自己的 IDE 里,然后接着调试代码.万一没有找到符合的条目,就只好去其他地方问

老码农眼中的CRM 图解

概述 喔家ArchiSelf CRM 是企业"以客户为中心"价值观的核心体现之一, 各种2B的应用都无可避免,而企业应用具有一定的复杂性,理解CRM系统也不是轻而易举的事情.在老码农的眼中,CRM 系统可能是这样的: 业务组成 业务单元的组成是第一位, 业务单元是企业的实在需求,也是采用CRM系统的主要因素. 如上所示,业务单元大约可以概括成9个方面. 客户管理 客户是第一位的, 先贤德鲁克的话不用赘述.客户管理包括什么呢? 人在业务中的重要性不言而喻.客户联系人管理包括建立联系人概况

老码农教你学英语

转自:http://blog.jobbole.com/45296/ 对于咱们这些高端大气.时刻需要和国际接轨的码农,英语的重要性自然是毋庸置疑的.尤其是那些胸怀大志的潜在大牛们,想在码农行业闯出一片天地,秒杀身边的小弟们,熟练掌握英语更是实现其目标最关键的因素之一.否则,试想在你捧着某出版社刚刚翻译出来的<JSP 高效编程>苦苦学习JSP模板的时候,你旁边的小弟却是拿着原版的<AngularJS in Action>学习开发单页面应用,虽然你们都同样认真地学习了一个月,可做出来东西

一个移动开发老码农的书单

了解更多老码农的个人信息,爱八卦的,请看这里:http://www.koulianbing.com/?page_id=12 老码农是个比较宅的人,不爱玩游戏,只爱看书.过去10年来读的书中,还能记得的书大部都是很不错的,列出来推荐给大家.会持续更新. 一.开发技术 1.Effective Objective C 2.0 适合代码量在5000行以后阅读,对细节优化,性能提升,结构设计都非常有帮助,强烈建议所有iOS码农人手一本,至少读三遍. 2.Objective-C高级编程 日本人写的,薄薄的一

37岁老码农现身说法:青春饭怎么吃?

程序员第一考虑的当然是技术,但现在真不知道学什么了:干了三四年的开发,手头的工作马马虎虎都没什么问题了.就算有问题,也是业务逻辑上的问题,系统太复杂,吃不透;或者系统里一些过时的/生僻的技术,真心觉得没必要花时间花精力去研究,能对付就行了,是不是?反正下家单位99.99%的几率是不会用到这些东西的的. 那么就是一些新技术了.新技术杂得很,不知道学什么,框架类库啥的其实没什么技术含量,一两个星期就可以上手,上手了之后呢?往深里学?其实和老旧技术一样的问题,谁知道下一份工作用不用得上呢!而且没趣,大

老码农谈NDK开发

关于NDK,我也天真过 5.6年前刚拿到HTC的G1开始做Android开发时,得知Java可以和C混编激动不已,真的是拿到钥匙见什么都是锁,老想着用NDK做些事情.到后来公司做了一个带有强烈技术风格的业务决策,我被迫把NDK来回折腾了很长时间,也没能折腾出什么成果,但这个决策却把公司折腾完蛋,我也就对NDK渐渐心恢意冷了,真正体会到,做业务,服务用户为主,技术上,好用是王道. 今天收到一封邮件(来自:[email protected]),让我谈谈NDK,真的挠到了我的痒处,一直有些话是想跟对N

逃离北上广之后,老码农的悲哀(顺便晒下简历,请围观,但请勿人肉,求放过!求无视!)

在此记录一下,逃离北上广之后的五个月后的今日的感想. 前戏: 最近老板出去旅游了,要十几天才回来.由于老婆最近总是在碎碎念,说小孩在成都读不起书,收入降低了这么多,真是不该回来!云云... 顺便说一下现状吧,本来是受朋友邀请才回来工作的,也就是现在的BOSS,我的王哥,王哥对我还是挺照顾的,也是非常的感谢.公司是做传统收银管理软件的,在现在的行业内一直是国内领先,效益还算可以,加上王哥自己开发有4个人,但是主力开发由于身体原因已经在家修养了半年多了,一直没来上班.由于软件是delphi开发的,面

退休老码农提醒你!学习Java,这些知识要牢记,能让你少走弯路!

现在的java在编程界基础已经根深蒂固了,随之带来的影响就是有大量的岗位,大量的工作方向,虽然现在很多的新兴语言势头都非常的猛烈,但是这并不影响java依然体量最大的编程语言,而且丝毫也看不出这门语言有任何衰减的趋势,依然有大量的从业人员在java开源领域贡献着大量的代码,在新兴的领域java切入进来也是毫不费力.创一个小群,供大家学习交流聊天如果有对学java方面有什么疑惑问题的,或者有什么想说的想聊的大家可以一起交流学习一起进步呀.也希望大家对学java能够持之以恒java爱好群,如果你想要

JS复制内容到剪贴板(兼容FF/Chrome/Safari所有浏览器)

现在浏览器种类也越来越多,诸如 IE.Firefox.Chrome.Safari等等,因此现在要实现一个js复制内容到剪贴板的小功能就不是一件那么容易的事了. 在FLASH 9 时代,有一个通杀所有浏览器的js复制内容到剪贴板的方案: 这个方案是一个最流行的方法: 著名的Clipboard Copy解决方案 利用一个clipboard.swf作为桥梁,复制内容到剪贴板. 原理是:创建一个隐藏的flash文件,同时给给flash的变量FlashVars 赋值“clipboard=..”,通过这个赋