41

直接剪切板粘贴上传图片的前端JS实现

 5 years ago
source link: https://www.zhangxinxu.com/wordpress/2018/09/ajax-upload-image-from-clipboard/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

这篇文章发布于 2018年09月21日,星期五,00:15,归类于JS实例。 阅读 112 次, 今日 112 次

byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8016

本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随意。

一、趁热打铁

上一篇文章也和剪切板粘贴相关,主要讲的是 输入框粘贴内容的体验优化 ,本文趁热打铁,继续介绍和剪切板API相关的一个交互功能,当当当当,就是页面Ctrl+V粘贴上传图片。

2AniYzR.jpg!web

二、如何获取剪切板中的图片?

不啰嗦,直接上代码:

document.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就是剪切板中的图片文件
});

我们在全局 document 对象上绑定一个 paste 粘贴事件,然后遍历剪切板对象 clipboardData 中的 items ,根据 type 类型确定图片,并执行 getAsFile() 方法将其转换成二进制的 file 对象,此 file 对象和 表单中的file文件上传<input>框 中的 file 对象,或者拖拽获取的 file 对象是同一个东西。

然后,我们直接ajax上传这个 file 对象,上传就成功了,就这么简单!

三、如何上传file对象?

实际开发,我们可以借助FormData对象进行上传,示意如下:

var formData = new FormData();
formData.append('file', file);
// 其他些参数,例如用户id
formData.append('userid', 1);
// ajax上传
var xhr = new XMLHttpRequest();
// 上传结束
xhr.onload = function () {
    var json = JSON.parse(xhr.responseText);
    // ... 这里处理返回的json数据
};
xhr.open('POST', './upload.php', true);
xhr.send(formData);

如果我们就传一个图片文件,没有其他乱七八糟数据,也可以直接send file 对象,例如:

// ajax上传
var xhr = new XMLHttpRequest();
// 上传结束
xhr.onload = function () {
    var json = JSON.parse(xhr.responseText);
    // ... 这里处理返回的json数据
};
xhr.open('POST', './upload.php', true);
xhr.send(file);

然后PHP后台直接 file_get_contents('php://input') 获取的就是图片数据了。

三、如果我想预览剪切板中的图片?

如果上传图片之前,或者上传过程中想要预览剪切板中的图像怎么办呢?也很简单,借助 FileReader 对象,轻轻松松几行就搞定。

var reader = new FileReader()
reader.onload = function(event) {
    // event.target.result就是图片的Base64地址啦
}
reader.readAsDataURL(file);

上面代码中的event.target.result就是图片的Base64地址,然后页面对应DOM元素位置插入如下HTML就可以看到图片效果了:

<img src="' + event.target.result + '">

四、实例demo

您可以狠狠地点击这里: JS实现页面粘贴图片直接Ajax上传demo

上传演示如下示意:

1. 复制图片

demo页面提供了图片素材,我们可以“右键-复制图片”,如下截图:

fq2mqyJ.png!web

2. 粘贴图片

Ctrl+V或者Commond+V粘贴。因为粘贴事件绑定在 document 上,因此,只有页面处于 focus 状态,粘贴既有效果。

ZfE77vN.png!web

3. 预览同时上传

此时,即触发预览和上传,不出意外,应该下面这般模样:

6VB7fun.jpg!web

由于本demo图片上传保存的最终图片均是用的剪切板中默认的同一个文件名,因此,如果多人同时上传,可能会出现被覆盖的情况,实际开发显然需要重命名哦。

本功能只能上传剪切板中的图片

本功能只能上传剪切板中的图片。

当我们使用QQ或者公司内部聊天工具中的截图工具截屏的时候,剪切板中是有截屏图片的;

当我们在任意网页中的图片上“右键-复制图片”,也是在剪切板中。

但是,但是,但是,我们在操作系统的文件夹中复制图片,不好意思,这个图片并不是在剪切板中,因此,无法上传。

这是个可能会让人困扰的地方。在windows文件夹系统中,我们复制文本类的东西,是在剪切板中,我们可以获得之;但是,复制的图片文件,不论是右键复制,还是Ctrl + C复制都不行。我曾经尝试找过“右键-复制到剪切板”这样的小工具,以便提高我们后台编辑人员的工作效率,失败了,如果谁知道有这样的工具,欢迎指教。

因此,桌面系统中的图片,目前实践下来,比较便捷的还是拖拽上传,以及文件选择框多选上传(demo参见这里)。

五、兼容性与渐进增强

自己测试了下,Chrome和Firefox浏览器都是OK的,Safari还没有测试,经验来看,应该没问题。关于是IE浏览器,并不支持。

首先, paste 事件必须在 contenteditable 的元素中才能执行,然后get不到 clipboardData 中的 items ,所以,放弃IE即可!

本身,剪切板直接上传图片就是一个渐进增强的功能。

实际开发是这样的:

<input type="file"> 上传是必备;拖拽上传是标配;粘贴上传则是VIP服务,锦上添花的事情,有更好,没有也只是和以前一样。

因此,所有用到图片上传的地方,我们都可以直接大胆多一个剪切板上传功能,韩信将兵多多益善。而且ajax上传这些都是重复利用的,实际就多了一点点代码量,性价比很高。

目前实际产品开发中用的比较多的是富文本编辑器中,例如知乎的文章编辑器,剪切板图片直接复制就可以上传:

QVjEBj6.jpg!web

看上去很高级,看了本文是不是觉得原来其实很简单,对吧。

好的体验有时候并不需要多么高深的技术,一个小小的技术tips足矣!

六、结束语

以前图片示例都使用张含韵,我这样的小站用用其实也不会有啥。不过我家领导比较胆小谨慎,老担心万一张含韵告我侵犯版权,到时候,卖房子都赔不起。我和我家领导在做决定的时候一向公平公正,意见相同的时候听我的,意见不同的时候听领导的。所以,这次,我就听了领导的话,张含韵所有图片下架,于是,数百篇文章,那是一篇一篇的过,所以版权图片全部替换掉(很多需要重新截图),花了我足足几个星期的业余时间。

然后顶替上来的图片是下面这位:

VRNVNz.jpg!web

名叫吴板泉,用了一段时间,结果那是反响平平,不对,是什么响都没有。

我琢磨了下,一定是年纪偏大,太熟了,而且还带了个装逼的墨镜是什么鬼!觉得必须得重新换图,于是,迎来了下面这位,叮叮叮叮:

3UzQZ3Y.jpg!web

这位小美女名叫陈晨玲,常用昵称是CC0,怎么样?是不是看上去很有心动的感觉。

IzmQRff.png!web

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。

本文地址: https://www.zhangxinxu.com/wordpress/?p=8016

(本篇完)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK