html 纯前端 原生 实现图片上传和拖拽功能

本文介绍了如何在HTML中使用拖拽功能上传文件,包括取消浏览器默认行为,处理不同类型的文件,使用FileReader读取文件路径,以及使用FormData和原生Ajax实现上传功能,同时涉及Base64编码和二进制文件流的转换。
摘要由CSDN通过智能技术生成

 笔记:

1.拖拽文件时要取消浏览器会打开文件的默认行为e.preventDefault();

2.拖拽文件回调的文件在e.dataTransfer.files[0],文件类型按钮input选择的文件(onchange触发方法)在e.srcElement.files[0]

3.获取文件路径   使用new FileReader()

4. FormData对象用以将数据编译成键值对,其主要用于发送表单数据

此处无接口上传可以忽略该方法

5. var reader = new FileReader();

reader.onload中的this指向 reader,其中的文件路径this.result为base64,若需要上传接口需要将其转换为二进制文件流

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
          width: 300px;
          height: 300px;
          padding-top: 30px;
          background-color: #f5f5f5;
          border-radius: 10px;
        }
        .btn {
          width: 200px;
          height: 30px;
          line-height: 30px;
          margin: 10px auto;
          text-align: center;
          border-radius: 4px;
          border: 1px dashed #ccc;
        }
        #img{
          width: 100px;
          height: 100px;
        }
        .addpic{
          width: 100px;
          height: 100px;
          border: 1px solid #ccc;
          display: flex;
          align-items: center;
          justify-content: center;
        }
      </style>
   
    
</head>
   
<body>
  <div>上传照片</div>
  <div class="box1" id="box1" style="display: flex;align-items: center;">
      <input type="file" id="file-btn" onchange="selectFile(event)" accept=".doc,.docx,.png" style="display: none;" >

        <div class="addpic" id="addpic">
             <img src="./加号.png">
        </div>
    
  </div>
  <div>上传文件</div>
  
    <div style="display: flex;align-items: flex-start;">
        <div class="box" id="drop">
            <div class="btn" id="btn">拖拽上传</div>
            
          </div>
          <div>
            <ul id="show">
            </ul>
          </div>
    </div>
   
  


  
  <script>

    var file = null // 要进行上传的文件
    var files=[]//文件数组
    // 给上传按钮绑定点击事件
    document.querySelector('.addpic').onclick = function() {
      // 模拟点击上传的input 弹出文件选择框
      document.querySelector('#file-btn').click()
      
    }





    // 获取点击上传  选择的文件
    function selectFile(e) {
      // 通过 e.target.files 获取到选择的文件 此处默认选择一个文件
      console.log('获取点击上传的文件---',e.srcElement.files[0]);
      console.log('原',e.srcElement.files[0])
      var reader = new FileReader();
          reader.readAsDataURL(e.srcElement.files[0]);
          console.log('this',reader)

          reader.onload = function(e){
                    console.log('新',e,'this',this)

                    var img = new Image();  
                    img.src = this.result;
                    img.setAttribute("id","img")
              
                    var add=document.getElementById("addpic")
                    
                    var p=document.getElementById("box1")
                    add.parentNode.insertBefore( img,add );  


                    resolve(img);
                }
       
         
    
    }
  
    // 拖拽上传获取对应文件
    let dropBox=document.querySelector('#drop');
        // 当文件在目标元素内移动时
        dropBox.addEventListener('dragover',function(e){
          // 阻止事件冒泡
          e.stopPropagation();
          // 阻止默认事件(与drop事件结合,阻止拖拽文件在浏览器打开的默认行为)
          e.preventDefault();
        })
        // 当拖拽文件在目标元素内松开时
        dropBox.addEventListener('drop',function(e){
          // 阻止事件冒泡
          e.stopPropagation();
          // 阻止默认事件(与dragover事件结合,阻止拖拽文件在浏览器打开的默认行为)
          e.preventDefault();
          // 获取拖拽上传的文件(files是个数组 此处默认限制只能上传一个)
          console.log('获取拖拽上传的文件---',e.dataTransfer.files[0]);
                var newLi=document.createElement("li")//创建一个div节点
                newLi.innerHTML=e.dataTransfer.files[0].name
                document.getElementById("show").appendChild(newLi);
          
          
        })
  </script>
  </body>
</html>

将base64转换为二进制文件流

dataURLtoBlob(dataurl) {
      var arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], {
        type: mime,
      });
    },

 原生ajax

	  // 上传函数
      function uplaod() {
        // 创建 FormData 对象
        var formData = new FormData();
        // 将获得文件对象追加到 FormData 对象中
        formData.append('file',file)
        // 创建 xhr 对象
        var xhr = new XMLHttpRequest()
        // 调用 open 函数,指定请求类型与URL地址。其中,请求类型必须为 POST
        xhr.open('POST', 'www.baidi.com')
        // 发起请求
        xhr.send(fd)
        // 监听 xhr.upload 的 onprogress 事件 获取上传进度
        xhr.upload.onprogress = function(e) {
            // e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度
            if (e.lengthComputable) {
            	// Math.round() 进行四舍五入取整 因为上传时 网络等不确定因素可能会出现缺失小部分字节的情况 
                // e.loaded 已传输的字节
                // e.total 需传输的总字节
                var progress = Math.round((e.loaded / e.total) * 100) + '%'
            }
        }
        // 是否上传成功
        xhr.onreadystatechange = function() {
          if (xhr.readyState === 4 && xhr.status === 200) {
            var data = JSON.parse(xhr.responseText)
            if (data.status === 200) {
              console.log('上传文件成功');
            }
          }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值