拖拽上传及读取文件实现

1.拖拽上传相关事件

2.拖拽上传简单实现

3.拖拽上传完整实现

4.读取文件实现

1.拖拽上传相关事件

相关事件:

  • ondragenter 拖着东西进入
  • ondragleave 拖着东西离开
  • ondragover 悬停
  • ondrop 松手

另外有时候需要阻止事件的默认事件发生:

1 // 以下是不同DOM绑定方法的阻止默认事件的方法
2 oForm.onsubmit=function (){
3   return false;
4 };
5 
6 oForm.addEventListener('submit', function (ev){
7   ev.preventDefault();
8 }, false);

2.拖拽上传简单实现

前端代码:

 1 <!-- author: wyb -->
 2 <!DOCTYPE html>
 3 <html>
 4 <head>
 5     <meta charset="utf-8">
 6     <title>文件拖拽上传</title>
 7     <style>
 8         .box {
 9             width: 400px;
10             height: 150px;
11             border: 1px solid black;
12             background: #CCC;
13             position: absolute;
14             margin-left: -200px;
15             margin-top: -75px;
16             left: 50%;
17             top: 50%;
18             text-align: center;
19             line-height: 150px;
20         }
21     </style>
22     <script>
23         window.onload = function () {
24             let oBox = document.querySelector('.box');
25 
26             oBox.ondragenter = function () {
27                 oBox.innerHTML = '松手上传';
28             };
29             oBox.ondragleave = function () {
30                 oBox.innerHTML = '请拖到这里';
31             };
32 
33             oBox.ondragover = function () {      //只要鼠标还没松手、并且还没离开,一直不停发生
34                 console.log("aaaa");
35                 // ondragover不阻止默认事件,ondrop不会触发  ->  在这里默认事件是浏览器打开这个文件
36                 return false;  // 阻止默认事件
37             };
38             oBox.ondrop = function (ev) {       // ev是事件对象event
39                 // alert('松手');
40 
41                 let data = new FormData();
42                 Array.from(ev.dataTransfer.files).forEach(file => {     // dataTransfer是传数据的
43                     data.append('f1', file);
44                 });
45 
46                 // Ajax:
47                 let oAjax = new XMLHttpRequest();
48 
49                 //POST
50                 oAjax.open('POST', `http://localhost:8080/api`, true);
51                 oAjax.send(data);
52 
53                 oAjax.onreadystatechange = function () {
54                     if (oAjax.readyState === 4) {
55                         if (oAjax.status >= 200 && oAjax.status < 300 || oAjax.status === 304) {
56                             alert('上传成功');
57                         } else {
58                             alert('上传失败');
59                         }
60                     }
61                 };
62 
63                 return false;
64             };
65         };
66     </script>
67 </head>
68 <body>
69 <div class="box">
70     请拖到这里
71 </div>
72 </body>
73 </html>

后端(express):

 1 const express = require('express')          // express主体
 2 const body = require('body-parser')         // 接收普通POST数据
 3 const multer = require('multer')            // 接收文件POST数据
 4 
 5 // create server:
 6 let server = express()
 7 server.listen(8080)
 8 
 9 // 中间件:
10 server.use(body.urlencoded({extended: false}))
11 let multerObj = multer({dest: './upload/'})
12 server.use(multerObj.any())
13 
14 // 处理请求: -> RESTful风格
15 server.post('/api', function (req, res) {
16     if(req.headers['origin']==='null' || req.headers['origin'].startsWith('http://localhost')){     // 设置允许跨域
17         res.setHeader('Access-Control-Allow-Origin', '*');
18     }
19 
20     res.send("test get")
21 
22     console.log(req.body);      // 普通POST数据
23     console.log(req.files);     // 文件POST数据
24 })
25 
26 // 设置静态文件路径
27 server.use(express.static('./www/'))

3.拖拽上传完整实现

相比较前面的简单实现,完整实现加了进度条,另外绑定事件全部使用了DOM3事件中的addEventListener

后端代码同基本实现,前端代码如下:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta charset="utf-8">
  5     <title>文件拖拽</title>
  6     <style media="screen">
  7         .box {
  8             width: 400px;
  9             height: 150px;
 10             border: 1px solid black;
 11             background: #CCC;
 12             position: absolute;
 13             margin-left: -200px;
 14             margin-top: -75px;
 15             left: 50%;
 16             top: 50%;
 17             text-align: center;
 18             line-height: 150px;
 19             display: none;
 20         }
 21         .progress{
 22             width: 99%;
 23             margin: 0 auto;
 24         }
 25         .parent {
 26             width: 500px;
 27             height: 20px;
 28             margin: 0 auto;
 29             border: 1px solid black;
 30         }
 31         .child {
 32             width: 0;
 33             height: 100%;
 34             background: green;
 35         }
 36     </style>
 37     <script>
 38         window.onload = function () {
 39             let oBox = document.querySelector('.box');
 40             let timer
 41 
 42             document.addEventListener('dragover', function (ev) {
 43                 clearTimeout(timer)
 44                 oBox.style.display = "block"
 45                 timer = setTimeout(function () {
 46                     oBox.style.display = "none"
 47                 }, 300)
 48 
 49                 ev.preventDefault()
 50             }, false)
 51 
 52             oBox.addEventListener('dragenter', function () {
 53                 oBox.innerHTML = '松手上传'
 54             }, false)
 55             oBox.addEventListener('dragleave', function () {
 56                 oBox.innerHTML = '请把文件拖到这';
 57             }, false)
 58 
 59             oBox.addEventListener('drop', function (ev) {       // ev是事件对象event
 60                 // alert('松手');
 61 
 62                 let data = new FormData();
 63                 Array.from(ev.dataTransfer.files).forEach(file => {     // dataTransfer是传数据的
 64                     data.append('f1', file);
 65                 });
 66 
 67                 // Ajax:
 68                 let oAjax = new XMLHttpRequest();
 69 
 70                 oAjax.upload.addEventListener('progress', function (ev) {
 71                     // 计算进度
 72                     let v = 100 * ev.loaded / ev.total + '%'
 73                     let oChild = document.getElementsByClassName('child')[0];
 74 
 75                     // 设置进度
 76                     oChild.style.width = v;
 77 
 78                     ev.preventDefault()
 79                 }, false)
 80 
 81                 //POST
 82                 oAjax.open('POST', `http://localhost:8080/api`, true);
 83                 oAjax.send(data);
 84 
 85                 ev.preventDefault()
 86             }, false)
 87         };
 88     </script>
 89 </head>
 90 <body>
 91     <div class="progress">
 92         <div class="parent">
 93             <div class="child">
 94 
 95             </div>
 96         </div>
 97     </div>
 98     <div class="box">
 99         请把文件拖到这
100     </div>
101 </body>
102 </html>

4.读取文件实现

使用FileReader实现读取文件:

基本用法:

 1 FileReader用法:
 2 let reader=new FileReader();
 3 
 4 reader.onload=function (){
 5   reader.result
 6 };
 7 
 8 reader.readAsXXX
 9 
10 
11 readAsText              文本
12 readAsDataURL           图片(以及其他二进制数据)
13 readAsBinaryString      以字符串形式存储的二进制数据
14 readAsArrayBuffer       以二进制数据的形式存储数据
15 
16 补充 - base64:
17 base64:可以把二进制数据表现成字符串
18 传输数据时可以直接用二进制,也可以用base64
19 另外只要能出现地址(src)的地方,都能用Base64
20 
21 base64的小应用——小图标不要引用地址,直接放个base64——优化网络性能
22 缺点:
23     1.维护麻烦
24     2.base64编码会把文件体积变大

代码 - 读取文本文件:

 1 <!-- author: wyb -->
 2 <!DOCTYPE html>
 3 <html>
 4 <head>
 5     <meta charset="utf-8">
 6     <title>读取文件内容</title>
 7     <style media="screen">
 8         .box {
 9             width: 400px;
10             height: 150px;
11             border: 1px solid black;
12             background: #CCC;
13             position: absolute;
14             margin-left: -200px;
15             margin-top: -75px;
16             left: 50%;
17             top: 50%;
18             text-align: center;
19             line-height: 150px;
20             display: none;
21         }
22     </style>
23     <script>
24         window.onload = function () {
25             let oBox = document.querySelector('.box');
26             let timer
27 
28             document.addEventListener('dragover', function (ev) {
29                 clearTimeout(timer)
30                 oBox.style.display = "block"
31                 timer = setTimeout(function () {
32                     oBox.style.display = "none"
33                 }, 300)
34 
35                 ev.preventDefault()
36             }, false)
37 
38             oBox.addEventListener('dragenter', function () {
39                 oBox.innerHTML = '请松手'
40             }, false)
41             oBox.addEventListener('dragleave', function () {
42                 oBox.innerHTML = '请把要读取的文件拖到这';
43             }, false)
44 
45             oBox.addEventListener('drop', function (ev) {       // ev是事件对象event
46                 let file = ev.dataTransfer.files[0]
47 
48                 // 读取文件 -> FileReader
49                 let reader = new FileReader()
50                 reader.onload = function (ev) {
51                     // alert(reader.result)
52                     document.write(reader.result)   // 直接将上传文件的内容(文本)写到页面中
53                 }
54                 reader.readAsText(file)
55 
56                 ev.preventDefault()
57             }, false)
58         };
59     </script>
60 </head>
61 <body>
62 
63 <div class="box">
64     请把要读取的文件拖到这
65 </div>
66 
67 </body>
68 </html>

代码 - 读取图片并选择上传:

  1 <!-- author: wyb -->
  2 <!DOCTYPE html>
  3 <html>
  4 <head>
  5     <meta charset="utf-8">
  6     <title>读取文件内容2</title>
  7     <style media="screen">
  8         * {margin:0; padding:0; list-style: none}
  9         .box {
 10             width: 400px; height: 150px; border: 1px solid black; background: #CCC;
 11             position: absolute; margin-left: -200px; margin-top: -75px; left: 50%; top: 50%;
 12             text-align: center; line-height: 150px; display: none;
 13         }
 14         .img-list{
 15             overflow: hidden;
 16         }
 17         .img-list li{
 18             float: left; width: 200px; height: 200px; border: 3px solid #666; position:relative; margin: 13px;
 19         }
 20         .img-list li img{
 21             width: 100%; height: 100%;
 22         }
 23         .img-list li .del-btn{
 24             position: absolute; right: 0; top: 0; display: inline;
 25         }
 26     </style>
 27     <script>
 28         window.onload = function () {
 29             let oBox = document.querySelector('.box');
 30             let oUl = document.querySelector('.img-list')
 31             let timer
 32 
 33             document.addEventListener('dragover', function (ev) {
 34                 clearTimeout(timer)
 35                 oBox.style.display = "block"
 36                 timer = setTimeout(function () {
 37                     oBox.style.display = "none"
 38                 }, 300)
 39 
 40                 ev.preventDefault()
 41             }, false)
 42 
 43             oBox.addEventListener('dragenter', function () {
 44                 oBox.innerHTML = '请松手'
 45             }, false)
 46             oBox.addEventListener('dragleave', function () {
 47                 oBox.innerHTML = '请把要读取并上传的图片拖到这';
 48             }, false)
 49 
 50             oBox.addEventListener('drop', function (ev) {       // ev是事件对象event
 51                 // 将上传的图片插入页面中
 52                 Array.from(ev.dataTransfer.files).forEach(function (file) {
 53                     // 确保上传的文件是图片
 54                     if(!file.type.startsWith('image/')){
 55                         return;
 56                     }
 57 
 58                     let reader = new FileReader()
 59                     
 60                     reader.onload = function () {
 61                         let oLi = document.createElement('li')
 62                         oLi.file = file
 63                         oLi.innerHTML = '<img src="" alt=""><a href="javascript:;" class="del-btn">删除</a>'
 64 
 65                         // 给图片标签加上src
 66                         let oImg = oLi.children[0]
 67                         oImg.src = this.result
 68 
 69                         // 删除图片
 70                         let oBtnDel = oLi.children[1]
 71                         oBtnDel.onclick = function () {
 72                             oUl.removeChild(oLi)
 73                         }
 74                         oUl.appendChild(oLi)
 75                     }
 76                     reader.readAsDataURL(file)
 77                 })
 78 
 79                 ev.preventDefault()
 80             }, false)
 81 
 82             // 上传
 83             let oBtnUpload = document.querySelector('#btn_upload')
 84             oBtnUpload.onclick = function () {
 85                 let data = new FormData
 86 
 87                 Array.from(oUl.children).forEach(function (li) {
 88                     data.append('f1', li.file)
 89                     // console.log(li.file)
 90                 })
 91 
 92                 // Ajax
 93                 let oAjax=new XMLHttpRequest();
 94 
 95                 // POST:
 96                 oAjax.open('POST', `http://localhost:8080/api`, true);
 97                 oAjax.send(data);
 98 
 99                 oAjax.onreadystatechange=function (){
100                     if(oAjax.readyState===4){
101                         if(oAjax.status>=200 && oAjax.status<300 || oAjax.status===304){
102                             alert('成功');
103                         }else{
104                             alert('失败');
105                         }
106                     }
107                 };
108 
109             };
110         };
111     </script>
112 </head>
113 <body>
114 
115 <ul class="img-list"></ul>
116 <input type="button" name="" value="上传" id="btn_upload">
117 <div class="box">
118     请把要读取并上传的图片拖到这
119 </div>
120 
121 </body>
122 </html>

读取图片并选择上传效果如下:

原文地址:https://www.cnblogs.com/wyb666/p/9740731.html