《大胖 • 小课》- 拖拽和剪贴板文件上传

简介: 这是《大胖小课》栏目的专题一《说说文件上传那些事儿》的第5节-《实现文件拖拽和剪贴板上传》专题已经更新章节:《大胖 • 小课》- 我是这样理解文件上传原理的《大胖 • 小课》- 写一个文件上传接口《大胖 • 小课》- 不用 js 实现文件无刷新上传《大胖 • 小课》- 玩玩多文件配多进度上传

这是《大胖小课》栏目的专题一《说说文件上传那些事儿》的第5节-《实现文件拖拽和剪贴板上传》

专题已经更新章节:

《大胖 • 小课》- 我是这样理解文件上传原理的

《大胖 • 小课》- 写一个文件上传接口

《大胖 • 小课》- 不用 js 实现文件无刷新上传

《大胖 • 小课》- 玩玩多文件配多进度上传

拖拽上传


html5的出现,让拖拽上传交互成为可能,现在这样的体验也屡见不鲜,实现上也比较简单。

主要是先定义好一个拖拽区域,从该拖拽区域的事件回调内得到文件的相关信息,前提是需要取消一些事件的默认行为,因为浏览器本身会自动打开或下载文件。

DEMO

befc2768a87c836576817a5bd7b0bc63_640_wx_fmt=gif&wxfrom=5&wx_lazy=1.gif

说明

  • 定义一个允许拖放文件的区域div.drop-box
  • 取消drop 事件的默认行为e.preventDefault();,不然浏览器会直接打开文件
  • 为拖拽区域绑定事件,鼠标在拖拽区域上 dragover, 鼠标离开拖拽区域dragleave, 在拖拽区域上释放文件drop
  • drop事件内获得文件信息e.dataTransfer.files

HTML

<div class="drop-box" id="drop-box">
       拖动文件到这里,开始上传
    </div>
    <button type="button" id="btn-submit">上 传</button>

JS

<script>
    var box = document.getElementById('drop-box');
    //禁用浏览器的拖放默认行为
    document.addEventListener('drop',function (e) {
        console.log('document drog');
        e.preventDefault();
    });
    //设置拖拽事件
    function openDropEvent() {
        box.addEventListener("dragover",function (e) {
            console.log('elemenet dragover');
             box.classList.add('over');
               e.preventDefault();
        });
         box.addEventListener("dragleave", function (e) {
              console.log('elemenet dragleave');
            box.classList.remove('over');
              e.preventDefault();
        });
        box.addEventListener("drop", function (e) {
            e.preventDefault(); //取消浏览器默认拖拽效果
            var fileList = e.dataTransfer.files; //获取拖拽中的文件对象
            var len=fileList.length;//用来获取文件的长度(其实是获得文件数量)
            //检测是否是拖拽文件到页面的操作
            if (!len) {
                box.classList.remove('over');
                return;
            }
            box.classList.add('over');
            window.willUploadFileList=fileList;
        }, false);
    }
    openDropEvent();
    function submitUpload() {
        var fileList = window.willUploadFileList||[];
        if(!fileList.length){
            alert('请选择文件');
            return;
        }
        var fd = new FormData();   //构造FormData对象
        for(var i =0;i<fileList.length;i++){
            fd.append('f1', fileList[i]);//支持多文件上传
        }
        var xhr = new XMLHttpRequest();   //创建对象
        xhr.open('POST', 'http://localhost:8100/', true);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                var obj = JSON.parse(xhr.responseText);   //返回值
                if(obj.fileUrl.length){
                    alert('上传成功');
                }
            }
        }
        xhr.send(fd);//发送
    }
    //绑定提交事件
    document.getElementById('btn-submit').addEventListener('click',submitUpload);
</script>

CODE

https://github.com/Bigerfe/fe-learn-code/tree/master/src/upfiles-demo/demo7

剪贴板上传


掘金的写文编辑器是支持粘贴上传图片的,比如我从磁盘粘贴或者从网页上右键复制图片。

DEMO

446044d824f8497c3fd073dfedb8d7b1_640_wx_fmt=gif&wxfrom=5&wx_lazy=1.gif

说明

  • 页面内增加一个可编辑的编辑区域div.editor-box,开启contenteditable
  • div.editor-box绑定paste事件
  • 处理paste 事件,从event.clipboardData || window.clipboardData获得数据
  • 将数据转换为文件items[i].getAsFile()
  • 实现在编辑区域的光标处插入内容 insertNodeToEditor 方法

问题1

测试中发现复制多个文件无效,只有最后一个文件上传,在掘金的编辑器里也同样存在,在坐有知道原因的可以留言说下。

问题2

mac系统可以支持从磁盘复制文件后上传,windows 系统测试未通过,剪贴板的数据未拿到。

HTML

<div class="editor-box" id="editor-box" contenteditable="true" >
       可以直接粘贴图片到这里直接上传
 </div>

JS

//光标处插入 dom 节点
    function  insertNodeToEditor(editor,ele) {
        //插入dom 节点
        var range;//记录光标位置对象
        var node = window.getSelection().anchorNode;
        // 这里判断是做是否有光标判断,因为弹出框默认是没有的
        if (node != null) {
            range = window.getSelection().getRangeAt(0);// 获取光标起始位置
            range.insertNode(ele);// 在光标位置插入该对象
        } else {
            editor.append(ele);
        }
    }
    var box = document.getElementById('editor-box');
    //绑定paste事件
    box.addEventListener('paste',function (event) {
        var data = (event.clipboardData || window.clipboardData);
        var items = data.items;
        var fileList = [];//存储文件数据
        if (items && items.length) {
            // 检索剪切板items
            for (var i = 0; i < items.length; i++) {
                console.log(items[i].getAsFile());
                fileList.push(items[i].getAsFile());
            }
        }
        window.willUploadFileList = fileList;
        event.preventDefault();//阻止默认行为
        submitUpload();
    });
    function submitUpload() {
        var fileList = window.willUploadFileList||[];
        var fd = new FormData();   //构造FormData对象
        for(var i =0;i<fileList.length;i++){
            fd.append('f1', fileList[i]);//支持多文件上传
        }
        var xhr = new XMLHttpRequest();   //创建对象
        xhr.open('POST', 'http://localhost:8100/', true);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                var obj = JSON.parse(xhr.responseText);   //返回值
                console.log(obj);
                if(obj.fileUrl.length){
                    var img = document.createElement('img');
                    img.src= obj.fileUrl[0];
                    img.style.width='100px';
                    insertNodeToEditor(box,img);
                   // alert('上传成功');
                }
            }
        }
        xhr.send(fd);//发送
    }

CODE

https://github.com/Bigerfe/fe-learn-code/blob/master/src/upfiles-demo/demo8/

目录
相关文章
|
7月前
|
前端开发
招投标系统是Electron的纯内网编辑Office Word,可以设置部分区域可编辑,其他的地方不能编辑吗?
我们是招投标系统的开发公司,框架是用的Electron,需要在纯内网的环境下编辑Office Word,可以设置部分区域可编辑,其他的地方不能编辑吗(如下红框位置)?并且在用户忘记填写一些区域的时候做提醒。
122 5
|
数据可视化 开发工具 git
只会Excel想做图表可视化,让数据动起来?可以,快来围观啦(附大量模板下载)
只会Excel想做图表可视化,让数据动起来?可以,快来围观啦(附大量模板下载)
|
Web App开发 JSON 前端开发
猿大师办公助手可实现微软Office Word文档在线安全预览,并且禁止编辑、拷贝、截屏、录屏、保存、导出、打印等!
现在,随着数字化进程渗透到到各行各业,数据安全已经成为了数字化革命中的重要组成部分,而在线Office成在OA、ERP、文档系统中得到了广泛的应用,为我国的信息化事业也做出了巨大贡献。随着操作系统、浏览器及Office软件的不断升级和更新换代,加上国家对信息化、数字化系统要求的不断提升,一些厂家的WebOffice控件产品不断被淘汰出局,而现存的几个产品也存在以下几个问题
431 0
|
JavaScript 容器
《大胖 • 小课》- 玩玩多文件配多进度上传
这是《大胖小课》栏目的专题一《说说文件上传那些事儿》的第4节-《玩玩多文件配多进度上传》 专题已经更新章节: 《大胖 • 小课》- 我是这样理解文件上传原理的 《大胖 • 小课》- 写一个文件上传接口 《大胖 • 小课》- 不用 js 实现文件无刷新上传 既然要说多文件配多进度上传,那就要看看单个进度是如何实现的。
120 1
《大胖 • 小课》- 玩玩多文件配多进度上传
|
JavaScript 开发者
ElUpload不好用?一文教你实现一个简易图片上传预览组件
ElUpload不好用?一文教你实现一个简易图片上传预览组件
2491 0
【C#】【桌面应用开发】拖拽文件到文本框获得所拖拽文件的路径
【C#】【桌面应用开发】拖拽文件到文本框获得所拖拽文件的路径
237 0
【C#】【桌面应用开发】拖拽文件到文本框获得所拖拽文件的路径
|
JavaScript 前端开发
干货 | web自动化总卡在文件上传和弹框处理上?
在有些场景中,需要上传文件,而 Selenium 无法定位到弹出的文件框,以及网页弹出的提醒。这些都是需要特殊的方式来处理。 input 标签使用自动化上传,先定位到上传按钮,然后 send_keys 把路径作为值给传进去. 如图所示,是企业微信文件上传的页面 定位到标签为 input,type 为 file 的元素信息,然后使用 send_keys 把文件路径作为值给传进去。 ![](h
|
异构计算
案例分享:Qt流水线图像显示控件(列刷新、1ms一次、缩放、拽拖、拽拖预览、性能优化、支持OpenGL GPU加速)
案例分享:Qt流水线图像显示控件(列刷新、1ms一次、缩放、拽拖、拽拖预览、性能优化、支持OpenGL GPU加速)
案例分享:Qt流水线图像显示控件(列刷新、1ms一次、缩放、拽拖、拽拖预览、性能优化、支持OpenGL GPU加速)
|
Unix 区块链 Android开发
VC++工具栏图标合并工具推荐:Axialis IconWorkshop
VC++工具栏图标合并工具推荐:Axialis IconWorkshop
241 0
VC++工具栏图标合并工具推荐:Axialis IconWorkshop