Skip to content
html
<!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>
    .upload-container {
      width: 500px;
      height: 100%;
      border: 1px solid #ebebeb;
      margin: 0 auto;
      margin-top: 50px;
      box-shadow: 3px 3px rgba(0, 0, 0, .3);
      padding: 0 30px;
      padding-bottom: 50px;
    }

    .upload-container .upload-btn {
      margin-top: 10px;
    }

    .upload-container .upload-btn .disabled {
      background-color: #dddddd !important;
    }

    .upload-container .upload-btn .select, .submit{
      height: 32px;
      background-color: #409eff;
      font-size: 12px;
      border: none;
      border-radius: 3px;
      color: #fff;
    }

    .upload-container .upload-btn .submit {
      margin-left: 10px;
    }
    
    .upload-container .upload-tip {
      font-size: 12px;
      color: #606266;
      margin-top: 10px;
    }

    .upload-container .upload-list {
      width: 360px;
    }

    .upload-container .upload-list .list {
      height: 26px;
      color: #606266;
      font-size: 14px;
      margin-top: 10px;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .upload-container .upload-list .active {
      color: #409eff;
    }

    .upload-container .upload-list .list .left .file {
      width: 14px;
      height: 14px;
    }

    .upload-container .upload-list .list .right .delete, .complete {
      width: 14px;
      height: 14px;
    }
  </style>
</head>
<body>
  <section class="upload-container">
    <input name="upload-inp" type="file" style="display: none;">
    <!-- <input name="upload-inp" type="file" accept=".png,.jpg,.jpeg,.webp" style="display: none;"> -->
    <div class="upload-btn">
      <button class="select">点击上传</button>
      <button class="submit">上传服务器</button>
    </div>
    <div class="upload-tip">
      只能上传JPG/PNG/JPEG/WEBP文件, 且大小不能超过500kb
    </div>
    <div class="upload-list">
      <!-- <div class="list">
        <div class="left">
          <img class="file" src="./static/imgs/file.png" alt="">
          <span>foo.jepg</span>
        </div>
        <div class="right">
          <img class="delete" src="./static/imgs/complete.png" alt="">
        </div>
      </div> -->
    </div>
  </section>

  <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/qs/6.10.1/qs.js"></script>
  <script src="./request.js"></script>
  <script>
    let uploadContainer = document.querySelector('.upload-container'),
      uploadInp = uploadContainer.querySelector('[name=upload-inp]'),
      uploadBtn = uploadContainer.querySelector('.upload-btn'),
      uploadList = uploadContainer.querySelector('.upload-list'),
      select = uploadBtn.querySelector('.select'),
      submit = uploadBtn.querySelector('.submit'),
      _file = null

    // 点击上传文件按钮, 触发input的点击事件
    select.addEventListener('click', function () {
      if (isDisabled()) {
        // 按钮禁用
        return
      }

      if (_file) {
        alert('一次只能上传一张图片~')
        return
      }

      uploadInp.click()
    })

    // 清除list
    function clearList () {
      _file = null
      uploadInp.value = ''
      uploadList.innerHTML = ''
    }

    // 禁用按钮
    function isDisabled () {
      return select.classList.contains('disabled') || submit.classList.contains('disabled')
    }

    // 选择图片时的处理
    uploadInp.addEventListener('change', function () {
      _file = this.files[0]

      /*
        lastModified: 1639485276476
        lastModifiedDate: Tue Dec 14 2021 20:34:36 GMT+0800 (中国标准时间) {}
        name: "img-1-263.webp" // 文件名
        size: 8996 // 文件大小, 单位B
        type: "image/webp" // 文件类型
        webkitRelativePath: ""
        [[Prototype]]: File
      */

      if (!_file) {
        return
      }

      // 限制图片类型方法1
      if (!/(jpg|png|jpeg|webp)/i.test(_file.type)) {
        alert('上传的图片格式不正确~')
        return
      }

      /*
        限制图片类型方法2
        <input name="upload-inp" type="file" accept=".png,.jpg,.jpeg,.webp">
        input-file属性
          accept 可选择的文件类型(不支持的类型会失去高亮)
            image/*, 只能选择图片
            .png,.jpg,.jpeg 只能选择png/jpg/jpeg格式的图片
          multiple 允许用户选择多个文件 
      */

      // 限制文件大小
      if (_file.size > 500 * 1024) {
        alert('文件太大了~')
        return
      }

      uploadList.innerHTML += `
        <div class="list">
          <div class="left">
            <img class="file" src="./static/imgs/file.png" alt="">
            <span>${_file.name}</span>
          </div>
          <div class="right">
            <img class="complete" src="./static/imgs/complete.png" alt="">
          </div>
        </div>
      `
    })
  
    // list样式
    uploadList.addEventListener('mouseover', function (event) {
      let list = uploadList.querySelector('.list'),
        img = list.querySelector('.right img')

      list.classList.toggle('active')
      img.src = './static/imgs/delete.png'
      img.className = 'delete'
    })

    uploadList.addEventListener('mouseout', function (event) {
      let list = uploadList.querySelector('.list'),
        img = list.querySelector('.right img')

      list.classList.toggle('active')
      img.src = './static/imgs/complete.png'
    })

    // 删除list
    uploadList.addEventListener('click', function (event) {
      if (!isDisabled() && event.target.className === 'delete') {
        clearList()
      }
    })

    // 上传图片
    submit.addEventListener('click', function () {
      if (isDisabled()) {
        // 按钮禁用
        return
      }

      if (!_file) {
        // alert('你还没有选择图片~')
        return
      }

      // 上传过程中禁用按钮
      select.classList.toggle('disabled')
      submit.classList.toggle('disabled')

      let formData = new FormData
      formData.append('file', _file)
      formData.append('filename', _file.name)

      // 上传图片
      instance.post('/upload-single', formData)
        .then(response => {
          if (response.status === 0) {
            // 上传成功
            alert('上传成功~')
          } else {
            return Promise.reject(response.statusText)
          }
        })
        .catch(reason => {
          // 上传失败 response.status = 1 / 响应码>=300
          alert('上传失败, 请稍后再试~')
        })
        .finally(() => {
          _file = null
          clearList()
          // 取消禁用
          select.classList.toggle('disabled')
          submit.classList.toggle('disabled')
        })
    })
  </script>
</body>
</html>