浏览器上传文件的文件选择方式包括:input 文件表单、拖放选择、直接粘贴剪贴板中的文件。之前写了 文件表单和拖放选择,这里就继续来写剪贴板粘贴上传。

注意!目前的粘贴上传只能粘贴保存在剪贴板中的文件,这些文件一般是截图工具之类的软件保存到剪贴板中的,在资源管理器中复制的文件不能粘贴上传。

读取剪贴板中的文件

JavaScript 代码如下:

//  给 document 添加 paste 事件
document.addEventListener('paste', ev => {
    const items = ev.clipboardData.items;  //  获取剪贴板中的数据
    let files = null;  //  用来保存 files 对象
    
    if (items.length > 0) {
        //  判断剪贴板中是否是文件
        if (items[0].kind == "file") {
            files = items[0].getAsFile();  //  获取文件
        }
    }
});

下面是用到的一些事件和属性说明:

paste 事件

当用户在浏览器发起粘贴操作时就会触发 paste 事件。

上面把 paste 事件绑定到了 document 上,只要在浏览器中按下 ctrl + v 就会触发。

clipboardData 对象

clipboardData 保存了一个 DataTransferDataTransfer 一般用来保存拖放操作的数据,但在粘贴操作时,数据也会保存在 DataTransfer 中。

下面是 lipboardData 包含的属性:

属性类型说明
filesFileList文件列表,在粘贴操作中为空
typesDOMStringList保存数据的类型列表
itemsDataTransferItemList剪贴板中的数据

items 就是剪贴板中的数据,下面是 items 的属性介绍:

属性类型说明
kindstring数据类型(filestring
typestring更详细的数据类型,例如 image/jpg

下面是 items 的方法介绍:

方法参数说明
getAsFile如果 kind 属性为 file 会返回文件。
getAsStringfunction如果 kind 属性为 string 可以获取剪贴板中的文本,需要传入一个回调函数,回调函数的参数就是剪贴板中的文本内容

items 是一个数组,因为一般情况下剪贴板中不会有多项内容,所以上面直接获取第 0 项。

获取了 files 对象后就可以直接通过 AJAX + FormData 上传了。关于 AJAX + FormData 上传文件可以看 使用AJAX + FormData 无刷新上传文件

浏览器兼容性

简单测试了一下,在 Chrome 和 Edge 可以正常使用,Firefox 和 Safari 因该也没问题,IE 11 不能使用。

为了兼容性考虑,在开发中可以准备多种上传方式。

预览图片

下面实现粘贴后显示图片:

//  给 document 添加 paste 事件
document.addEventListener('paste', ev => {
    const items = ev.clipboardData.items;  //  获取剪贴板中的数据
    let files = null;  //  用来保存 files 对象
    
    if (items.length > 0) {
        //  判断剪贴板中是否是文件
        if (items[0].kind == "file") {
            files = items[0].getAsFile();  //  获取文件
            //  判断是否是图片
            if (files.type == 'image/jpeg' || files.type == 'image/png') {
                const reader = new FileReader();  //  创建 FileReader 对象
                reader.readAsDataURL(files);  //  读取文件
                
                //  读取完成后触发
                reader.addEventListener('load', ev => {
                    const img = document.createElement('img');  //  创建 img 标签
                    img.src = ev.target.result;  //  设置 img 的 src
                    document.body.appendChild(img);  //  把创建的 img 插入到 body 中
                });
            }
        }
    }    
});

HTML 的 body 中没有任何元素,所以 paste 事件就直接绑定到了 document ,只要在浏览器中按 ctrl + v 图片就会直接插入到 body 中。

更详细的关于本地图片预览的说明可以查看:JavaScript 拖拽文件上传和本地图片预览

相关文章: