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

简介: 这是《大胖小课》栏目的专题一《说说文件上传那些事儿》的第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/

目录
相关文章
|
JavaScript
Fastadmin列表的多图预览(一行代码)
Fastadmin列表的多图预览(一行代码)
359 0
|
6月前
|
搜索推荐
【sgUploadTray_v2】自定义组件:升级版上传托盘自定义组件,可实时查看上传列表进度,可以通过选项卡切换上传中、成功、失败的队列,支持翻页,解决了列表内容太多导致卡顿的情况。(一)
【sgUploadTray_v2】自定义组件:升级版上传托盘自定义组件,可实时查看上传列表进度,可以通过选项卡切换上传中、成功、失败的队列,支持翻页,解决了列表内容太多导致卡顿的情况。
【sgUploadTray_v2】自定义组件:升级版上传托盘自定义组件,可实时查看上传列表进度,可以通过选项卡切换上传中、成功、失败的队列,支持翻页,解决了列表内容太多导致卡顿的情况。(一)
|
6月前
|
前端开发
前端实现拖拽上传
前端实现拖拽上传
100 1
uniapp 文本复制及文件预览
uniapp 文本复制及文件预览
168 0
让你的 VSCode 文件图标更好看的10个文件图标主题
一个好用的文件图标主题除了能够愉悦身心之外,对于开发的效率也会有很大的提升,可以帮助我们更快地找到需要的文件,或者发现文件命名中的错误。这篇文章总结了我用过的最棒的 10 个文件图标主题。
1907 0
让你的 VSCode 文件图标更好看的10个文件图标主题
|
测试技术 数据库 数据安全/隐私保护
推荐一个牛逼的开源在线文档系统,支持Markdown和富文本编辑模式!
推荐一个牛逼的开源在线文档系统,支持Markdown和富文本编辑模式!
3674 0
推荐一个牛逼的开源在线文档系统,支持Markdown和富文本编辑模式!
【C#】【桌面应用开发】拖拽文件到文本框获得所拖拽文件的路径
【C#】【桌面应用开发】拖拽文件到文本框获得所拖拽文件的路径
228 0
【C#】【桌面应用开发】拖拽文件到文本框获得所拖拽文件的路径
|
JSON 移动开发 JavaScript
快速搭建一个代码在线编辑预览工具
快速搭建一个代码在线编辑预览工具
440 0
快速搭建一个代码在线编辑预览工具
使用APICloud实现文档下载和预览功能
使用 APICloud 开发 app 时,可以使用 api.download 方法实现下载;预览文档可以使用 superFile 模块。superFile 模块封装了基于腾讯浏览服务 TBS,使用 X5Webkit 内核,实现文件的展示功能,支持多种文件格式(PDF、Word、Execl、TXT、PPT)。
490 0