利用 ClipboardData 在网页上粘贴 QQ 截图

最近到知乎评论框可以直接粘贴来自 QQ 或者其他截图工具的图片,比较好奇。以前一直用的 Ueditor 也有这个功能并且还带截图工具,没怎么关注其实现方式。今天扒下代码,学习下记录下。

关键的 ClipboardData 对象

DOM元素的 cut、copy 和 paste 事件的 clipboardData 属性保存了一个 DataTransfer 对象,这个对象可用于:

  • 描述哪些数据可以由 cut 和 copy 事件处理器放入剪切板,通常通过调用 setData(format, data) 方法;
  • 获取由 paste 事件处理器拷贝进剪切板的数据,通常通过调用 getData(format) 方法

实现方式

这里获取剪贴板的图片肯定是通过 paste 事件。可以通过 clipboardData 的类型 types 来判断剪贴板里面的内容是文件还是文字,然后再在 clipboardData.items 中取出来。
这里取出来的是二进制文件,我们可以通过 Local IO 的 FileReader 来读取。也可以像知乎那样使用 H5 中 FormData 存储,再 post 到服务端换回一个 Image 标签。

注意:

  • 以上的 FileReaderFormData 都只有现代浏览器才支持。
  • Firefox 和 IE 11 不允许直接粘贴图片的,需要在 DOM 元素上设置 contenteditable=”true”。 chrome 的是 g_editable=”true”

Talk is cheap. Show me the code.

div 用来粘贴图片,img 用来显示。

1
2
<div id='divEdit' g_editable="true" contenteditable="true">点击我粘贴图片</div>
<img src="" id="myImageLoadDemo" /></div>

监听 div 的 paste 事件,获取剪贴板内容,判断类型,读取图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var divEdit = document.getElementById('divEdit');
divEdit.addEventListener('paste', function (event) {
// 添加到事件对象中的访问系统剪贴板的接口
var clipboardData = event.clipboardData,
i = 0,
items, item, types;
if (clipboardData) {
console.log('your browser support clipboardData');
items = clipboardData.items;
if (!items) {
return;
}
item = items[0];
// 保存在剪贴板中的数据类型
types = clipboardData.types || [];
for (; i < types.length; i++) {
if (types[i] === 'Files') {
item = items[i];
break;
}
}
// 判断是否为图片数据
if (item && item.kind === 'file' && item.type.indexOf("image")) {
// 读取图片
imgReader(item);
}
}
});
var imgReader = function (item) {
var file = item.getAsFile(),
//使用 local IO 来读取文件显示
//或者 post 到服务端生成 image 标签
reader = new FileReader();
reader.onload = function (e) {
document.getElementById('myImageLoadDemo').setAttribute('src', e.target.result);
};
// 读取文件
reader.readAsDataURL(file);
};

例子

分享到 评论