兼容PC+手机端,Chrome 42+、Edge 12+、Firefox 41+、IE、Opera 29+、Safari 10+,PC支持复制图片,手机端友好交互。其中:
- clipboard.js
- window.clipboardData 兼容IE
- 友好型补充(主要针对移动端)
最近做了一个需要 一键复制 功能的网站,也是经历了一番挣扎,下面给出自己的一些总结,欢迎大家补充。
<input id="foo" value="https://github.com/zenorocha/clipboard.js.git">
<button class="btn" data-clipboard-action="copy" data-clipboard-target="#foo" data-clipboard-text="我是复制的内容,和前一个属性选其一使用">
<img src="assets/clippy.svg" alt="Copy to clipboard">
button>
<script>
// 通过选择触发节点实例化复制/剪切功能(必须)
var clipboard = new Clipboard('.btn');
// 复制成功or失败后的回调函数,可以弹窗(toast)提示(可选)
clipboard.on('success', function(e) {
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
script>
其中
3.使用方法@2 function
new Clipboard('.btn', {
target: function(trigger) {
return trigger.nextElementSibling; // 目标内容为出发节点的下一个节点
// return trigger.previousElementSibling; // 前一个节点
// return trigger.parentElement; // 父节点
// return document.getElementById('id'); // 直接 }
});
new Clipboard('.btn', {
text: function(trigger) {
return trigger.getAttribute('aria-label');
// return trigger.nextElementSibling.innerText;
// return document.getElementById('id').innerText;
}
});
new Clipboard('.btn', {
container: document.getElementById('modal')
});
这种是实例化的时候添加复制目标,添加目标方式有:
container 这个我没用过,理解应该是返回复制内容的盒子节点,那就跟target类似了。官方解释是:
For use in Bootstrap Modals or with any other library that changes the
focus you’ll want to set the focused element as the container value.
4.clipboard.js的一些其他方法:
那就是IE8及以下了,因为IE有个clipboardData方法,所以需要兼容的话可以解决,使用这个方法操作的时候会有弹窗提示用户是否允许访问剪贴板
if (Clipboard.isSupported()) {
// 使用clipboard.js处理
}else if(window.clipboardData){
var btn = document.getElementById('btn'); // 触发节点
var copyText = document.getElementById('btn').innerText // 或value,要复制的内容
btn.onclick = function(){
window.clipboardData.setData('Text', copyText);
}
}else{
alert('您目前的浏览器不支持一键复制,请手动复制使用其他浏览器试试')
}
当然这部分主要是手机端了,主要是让其更好的完成手动长按复制,那IOS好像有些地方长按并不会有反应(出现复制、全选等)。这种情况一般出现在非input/textarea(个人感觉clipboard.js对input的支持更好一些,但input内容不能换行…textarea移动端有时候会有问题)标签下,比如div,那怎样让其支持呢?
<div contenteditable="true" onkeydown="return false;" onpaste="return false;">
内容1<br>
内容2
div>
contenteditable属性可以让盒子内容处于可以编辑状态,我们只要这个状态,而不是让用户真的能编辑onkeydown="return false;" onpaste="return false;"
禁用键盘和右键粘贴
针对IOS的Safari 10以下或者不支持clipboard.js的环境,有更好的用户体验方案,那就是用户点一下复制内容就自动帮其全部选中,这样用户只需点击复制
针对div contenteditable:
document.addEventListener('selectionchange', function(){
var t = window.getSelection().anchorNode;
var tParent = t.parentNode.id == 'mobileCopyText'; //className亦可
if (t && tParent && t.parentNode.innerText != window.getSelection()) {
window.getSelection().selectAllChildren(tParentNode)
}
})
简单解释一下原理:就是给 选区内容改变(selectionchange)(光标位置也会触发)添加一个监听事件,一旦触发,当(if条件)
这个时候选中 复制内容的父节点(有时候你可能需要parentNode两次)下的所有内容
关于getSelection()感兴趣的可以自己了解更多
针对input:
$('input').focus(function(){
$(this).select()
})
可能有人会问这么好的事情为什么说是只针对IOS,原因是测试发现Android下有些怪异的现象,那就是通过这种方法全选中后你点复制,但事实上你并没有复制到内容(尴尬)可能是个别浏览器的锅。所以最好还是判断一下IOS再用吧,怎么判断这里就不说了。另外手机端如何复制到图片还没有方案。