我们或多或少都使用过各式各样的富文本编辑器,其中有一个很方便功能,复制一张图片然后粘贴进文本框,这张图片就被上传了,那么这个方便的功能是如何实现的呢?
原理分析:
复制=>粘贴=>上传
在这个操作过程中,我们需要做的就是:监听粘贴事件=>获取剪贴板里的内容=>发请求上传
需要明白的是:
我们只能上传截图工具截的图片(qq截图、微信截图等),不能粘贴上传系统里的图片(从桌面上、硬盘里复制),因为他们是存在完全不同的地方。
知悉paste event这个事件:当进行粘贴(右键paste/ctrl+v)操作时,该动作将触发名为'paste'的剪贴板事件,这个事件的触发是在剪贴板里的数据插入到目标元素之前。如果目标元素(光标所在位置)是可编辑的元素(设置了contenteditable属性的div。textarea并不行),粘贴动作将把剪贴板里的数据,以最合适的格式,插入到目标元素里;如果目标元素不可编辑,则不会插入数据,但依然触发paste event。数据在粘贴的过程中是只读的。
监听了paste事件,也知道了表现形式,接下来就是如何获取数据了:
chrome有特定的方法,利用clipboardData.items、getAsFile()、new FileReader()等api可以在paste回调函数里获取到剪贴板里图片的base64编码字符串(无论是截图粘贴的还是网页图片复制粘贴的),ie11,firefox没有这样的api,不过依然有办法可以获取,因为数据已经表现在img的src里了,对于截图粘贴的,直接取img的src属性值(base64),对于网页粘贴的,则把地址传给后台,然后根据地址down下来,存在自己的服务器,最后把新地址返回来交给前端展示就ok了。为了保持一致性便于管理,统一将所有情况(截图、网页)中的img的src属性替换为自己存储的地址。
完整例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Js实现粘贴上传图片</title>
<script src="jquery.js"></script>
</head>
<body>
复制粘贴上传图片:
<div id="content_img" contentEditable="true" style="width:500px;height:500px;border:1px solid #000;"></div>
<script>
document.getElementById('content_img').addEventListener('paste', function(e) {
if (!(e.clipboardData && e.clipboardData.items)) {
return;
}
for (var i = 0, len = e.clipboardData.items.length; i < len; i++) {
var item = e.clipboardData.items[i];
if (item.kind === "string") {
item.getAsString(function(str) {
console.log(str);
alert("请粘贴图片上传");
})
$("#content_img").html("");
} else if (item.kind === "file") {
var blob = item.getAsFile();
console.log(blob);
if (blob.size === 0) {
return;
}
var data = new FormData();
data.append("image", blob);
$.ajax({
url: "http://www.yzmcms.com/upload.php",
type: 'POST',
cache: false,
data: data,
processData: false,
contentType: false,
dataType: "json",
success: function(result) {
console.log(result);
if (result.status) {
var html = "<img src=" + result.data + " width='100' height='100'>";
$("#content_img").append(html);
} else {
console.log(result.message)
}
}
});
//阻止默认行为即不让剪贴板内容在div中显示出来
e.preventDefault();
}
}
});
</script>
</body>
</html>