zoukankan      html  css  js  c++  java
  • 拖拽上传及读取文件实现

    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>

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

  • 相关阅读:
    C++11 override和final
    C++11 类型推导auto
    C++11 强枚举类型
    C++11 explicit的使用
    《数据结构与算法之美》——冒泡排序、插入排序、选择排序
    《数据结构与算法之美》- 栈
    Spring Boot系列——AOP配自定义注解的最佳实践
    Spring Boot系列——死信队列
    Spring Boot系列——7步集成RabbitMQ
    让我头疼一下午的Excel合并单元格
  • 原文地址:https://www.cnblogs.com/wyb666/p/9740731.html
Copyright © 2011-2022 走看看