故事背景,需要直接在页面上点击一键粘贴按钮,自动复制服务生成的图片到剪贴板方便业务一些粘贴发送给客户。
1、开始做法,使用原生的document.execCommand('copy')进行复制,代码如下。虽然也能实现了图片的复制,但粘贴的结果不是很理想,有些只能在微信上粘贴,钉钉、浏览器富文本上不能;有些是微信可以钉钉、富文本不行。总之就会出现有些黏贴不到的情况。
#原生js写法
const targetPic = new Image()
targetPic.onload = e => {
targetPic.setAttribute('contenteditable', true)
document.body.appendChild(targetPic)
const selection = window.getSelection()
const range = document.createRange()
range.selectNode(targetPic)
selection.removeAllRanges()
selection.addRange(range)
document.execCommand('copy')
targetPic.setAttribute('contenteditable', false)
document.body.removeChild(targetPic)
this.isuTip.success('复制成功')
this._recordUserBehavior(32)
this.dispatchEvent(new CustomEvent('has-send-quote', {bubbles: true, composed: true}))
this.cancel()
}
targetPic.src = targetUrl
2、然而需求就是要实现这样一个功能,无奈只能另外寻找法子。
回过头看看,浏览器是如何获取剪切板中的图片?
ocument.addEventListener('paste', function (event) {
var items = event.clipboardData && event.clipboardData.items;
var file = null;
if (items && items.length) {
// 检索剪切板items
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf('image') !== -1) {
file = items[i].getAsFile();
break;
}
}
}
// 此时file就是剪切板中的图片文件
});
直接上代码如上所示,就是直接从clipboardData.items 中获取图片文件进行处理的(经过调试发现,原先的方法复制出来的图片,浏览器识别为html格式不是文件格式)。那么直接往clipboardData.items写入图片文件不就可以了?查询了一下,果然有对应的api。使用如下,果然行的通。
const data = await fetch(`/img.img1.png`)
// const data = await fetch('/management/attachments/63848472471ea1095093874a498d25dba07d478a.do')
const blob = await data.blob()
await navigator.clipboard.write([
// eslint-disable-next-line no-undef
new ClipboardItem({
[blob.type]: blob
})
])
console.log('Fetched image copied.')
} catch (err) {
console.error(err.name, err.message)
注: 浏览器为了安全,navigator.clipboard必须在https下才能使用