js复制到粘贴板命令及第三方插件 clipboard 、ZeroClipboard

来源:互联网 发布:扫描仪软件通用版 编辑:程序博客网 时间:2024/05/17 01:07

最近做的一个项目中,有一个点击按钮后,复制文本的需求,关于使用 JS复制文本的情况,很久以前曾经看到过,不过也仅是稍稍有些印象,对于到底如何复制,是否有什么兼容性要求等,都一概不知,但觉得应该没什么难度的。

但是当我自己真正做起来的时候,才发现这其中存在不少坑,各种浏览器实现复制的方法都不一样,而且无论怎么做兼容,似乎都不可能让所有的浏览器都能实现复制到粘贴板的功能。

几种主要方法总结如下。


execCommand

关于复制到粘贴板的功能,网上出现频率最多的方法就是 execCommand

原理其实很简单明确,首先获取你想要复制的文本所在的元素,使用 js选择器即可,例如 document.getElementById('txt'),然后使用 select选择到文本,最后调用 execCommand方法进行复制。

function copy(){    let ele = document.getElementById('txt')    ele.select()    document.execCommand('Copy')}

我用最新版 Chrome试验了一下,这里的 select()方法只对 input 或者 textarea 元素有效,只有txt是 这两个元素时,才有可能复制成功,其他元素全部失败。

这里需要说明的是,document.execCommand() 方法有很多参数,Copy只是其中一个:

// 选中网页中的全部内容document.execCommand('selectAll')// 打开 命令,相当于单击文件中的打开按钮document.execCommand('open)// 另存为 命令,将当前页面另存为document.execCommand('saveAs)// 打印 命令,需要存在打印机document.execCommand('print)// 剪贴选中的文字到剪贴板document.execCommand('Cut','false',null)// 删除选中的文字document.execCommand(Delete','false',null)....等等

以上就是document.execCommand()其中一部分使用方法,当然了,兼容性堪忧,几乎没什么浏览器实现,我用最新版的 Chrome操作以上方法,没一个有响应的。

除了配合 select之外,input元素还有一个 focus方法,同样可以达到此目的,例如,下面这段我直接从 MDN 抄来的代码。

<p>点击复制后在右边textarea CTRL+V看一下</p><input type="text" id="inputText" value="测试文本"/><input type="button" id="btn" value="复制"/><textarea rows="4"></textarea><script type="text/javascript">    var btn = document.getElementById('btn');    btn.addEventListener('click', function(){        var inputText = document.getElementById('inputText');        var currentFocus = document.activeElement;        inputText.focus();        inputText.setSelectionRange(0, inputText.value.length);        document.execCommand('copy', true);        currentFocus.focus();    });</script>

我在谷歌浏览器上实验了一下,没什么卵用,因为人家已经注明了,除了 Firefox之外,其他浏览器全都没实现。


clipboardData

这个方法算是 IE的私有方法,有的文章上说 firefox也支持,可能之前比较古老的版本支持吧,我用最新版的火狐测试了一下,根本没用,其他浏览器应该也都没有(最起码我的chrome浏览器就不行。)

function copyToClipBoard(){    var clipBoardContent+=window.location.href;    window.clipboardData.setData("Text",clipBoardContent);    alert("复制成功");}

上面代码我在 IE上试了一下,确实可行,不过其他浏览器就没反应了,因为根本没有 clipboardData这个方法。

IEclipboardData除了 setData这个方法之外,还有 getData(sDataFormat) 从剪贴板获取指定格式(text, url)的数据,以及清除剪贴板中指定格式(text, url)的数据 clearData(sDataFormat)

createTextRange

这个方法也只有在 IE下能用,我用 chrome 360se firefox分别测了一遍,全都报错。

<input onclick="goCopy(this)" value="这是要复制的内容">function goCopy(obj){    obj.select()    textRange=obj.createTextRange()    textRange.execCommand("Copy")    alert("复制成功!")}

这种方法似乎和第一种方法一样,但是还另外多了一行代码,就是这一句 js=obj.createTextRange() ,如果你要复制input或者 textarea元素中的所有内容,那么多出来的这一句是多此一举,但是如果你要只复制其中一部分文本,那么 这个 createTextRange()就能派上用场了,因为这个获得了 obj.createTextRange()的引用对象 textRange,还有其他的一些方法和属性,能够使得复制操作的颗粒度更小。

属性

属性名 描述 boundingHeight 获取绑定 TextRange对象的矩形的高度 boundingLeft 获取绑定TextRange 对象的矩形左边缘和包含TextRange对象的左侧之间的距离 offsetLeft 获取对象相对于版面或由offsetParent属性指定的父坐标的计算左侧位置 offsetTop 获取对象相对于版面或由offsetParent属性指定的父坐标的计算顶端位置 htmlText 获取绑定TextRange对象的矩形的宽度 text 设置或获取范围内包含的文本

方法

方法名 描述 moveStart(‘character’, 2) 更改范围的开始位置 moveEnd 更改范围的结束位置 collapse 将插入点移动到当前范围的开始或结尾 move 折叠给定文本范围并将空范围移动给定单元数 execCommand 在当前文档、当前选中区或给定范围上执行命令 select 将当前选择区置为当前对象 findText 在文本中搜索文本并将范围的开始和结束点设置为包围搜索字符串。

以上属性和方法在 IE中皆有效,其他浏览器都不行。


第三方库

关于复制粘贴功能,基本上就是以上三种了,其他的也都是从这三种方法中细化出来的方法,只是一个复制到粘贴板的功能就有那么多注意事项,还有那么多的兼容性代码要写,而且写了之后还不一定所有浏览器都能用,简直就是难为人嘛,不过按照我经验来看,这种情况越复杂繁琐,就越意味着妥妥的是要有第三方库的节奏啊,搜了一下,果然是有。

  • ZeroClipboard.js

ZeroClipboard.js是使用动态创建 flash的方式,并利用 flash将需要粘贴的文本或者其他对象粘贴到粘贴板的,也就是说需要浏览器支持 flashflash的支持度确实很高,几乎所有浏览器都支持,但有的浏览器并不是默认支持 flash,必须要用户自己主动安装才行,比如 chrome,所有如果浏览器没有 flash,那么此库是用不了的。

除了一小部分不默认安装 flash的浏览器之外,此库在桌面上的兼容性很好,但是如今移动端基本上都是不支持 flash的,所以想要在移动端用,还是悠着点好。

  • clipboard.js

clipboard.js算是一个新锐了,在 github上迄今为止有 18500多颗星,号称是专为现代浏览器设计的复制粘贴方案,不使用 flash,不依赖其他库,gzip压缩之后只有 3kb的大小,兼容性为 IE9+

这里写图片描述

此库实现复制粘贴功能使用的关键方法就是上面说到的 select()execCommand两种结合,原理就是创建出一个隐藏的 input或者 textarea元素,结合两种方法进行复制粘贴。

这种方法在移动端也能用 ,但并不是所有的移动端浏览器都能用,据我测试情况来看,百度浏览器和chrome移动端都是可以用的,但是 QQ浏览器uc浏览器都不支持,如果不是必须要兼容所有浏览器,推荐使用此库,因为你能用更现代的方式来组织代码,例如在 vue等框架中使用此库。

以下为在 vue中使用 clipboard.js添加点击复制到粘贴板的功能示例。

<template>  <a href="javascript:;" @click="copyWx" :data-clipboard-text="wechat">复制微信</a></template><script>  // 引入 clipboard  import Clipboard from 'clipboard'  export default {    name: 'copyToClipboard',    props: ['wechat'],    methods: {      copyWx () {        let clipboard = new Clipboard('.wx')        clipboard.on('success', e => {          // 释放内存          clipboard.destroy()        })        clipboard.on('error', e => {          // 不支持复制          alert('浏览器不支持自动复制,请手动复制微信号')          // 释放内存          clipboard.destroy()        })      }  }</script>

clipboard.jsZeroClipboard.js二者相比各有优势,前者适合现代浏览器,使用方法也更加 modernfashion,更贴近目前前端领域的发展趋势,这从它在github上的 star数量就可见一斑,后者则兼容性更强,虽然 flash目前已经宣布正式退休,但 想要让 flash彻底消失,还需要不短的时间,在这段时间内,ZeroClipboard.js依然可以有所作为。

阅读全文
0 0
原创粉丝点击