【Effective Web】文件上传


前言

前端无法像app一样直接操作本地文件,对本地文件的操作和上传,通常使用以下三种方式:

  1. 通过input type = file 选择本地文件上传,这是最常见的方式
  2. 通过拖拽的方式把文件拖过来
  3. 在编辑框里面复制黏贴,这种方式常见于上传图片。

一、选择本地文件

1.设计一个上传文件按钮

通过input type = file 选择本地文件上传,通常会自定义一个按钮,然后盖在上面,因为type=file的input不容易改变样式。
这里使用label做样式覆盖,label 元素不会向用户呈现任何特殊效果。不过,它为鼠标用户改进了可用性。如果在 label 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。

注意:label中的for属性应与input元素的id一致

    <form id="form">
      <label for="submit">
        <div class="lBut">
          <span>选择文件</span>
        </div>
      </label>
      <input id="submit" type="file" />
    </form>
  #submit {
    display: none;
  }
  .lBut {
    width: 87px;
    height: 24px;
    font-size: 14px;
    line-height: 24px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 4px;
    margin-left: 28px;
    transition: all 0.5s;
    white-space: nowrap;
    background-color: #409eff;
    color: white;
    border: 1px solid #409eff;
  }

而通过表单选择的文件无法直接获取文件真实存放路径,文件里面内容也无法查看。formData格式的文件可以作为接口参数传给后台。

  const inputFile = document.getElementById("submit");
  const form = document.getElementById("form");

  inputFile.addEventListener("change", function () {
    let formData = new FormData(form);
    console.log("formData :>> ", formData);
    console.log("inputFile.value :>> ", inputFile.value);
  });

在这里插入图片描述

2.FileReader读取文件内容

当选择文件后,触发input的change事件,在change的回调方法中初始化一个fileReader对象,fileReader有一个方法readAsDataURL可以读取文件并转为base64格式。在fileReader读取文件后触发onload回调方法,在回调方法中获取文件的结果,并创建一个img元素把结果作为src属性值,展示在页面上。
js代码如下:

const inputFile = document.getElementById("submit");
  const form = document.getElementById("form");

  inputFile.addEventListener("change", function () {
    let file = inputFile.files[0];
    if (!file) return;
    console.log("file :>> ", file);

    // 读取文件并转化为base64格式
    let fileReader = new FileReader();
    fileReader.readAsDataURL(file);

    fileReader.onload = function () {
      console.log("fileReader :>> ", fileReader);
      if (/^image\/[jpeg|png|gif]/.test(file.type)) {
        let img = document.createElement("img");
        img.src = fileReader.result;
        img.style.width = "500px";
        document.body.append(img);
      }
    };
  });

在这里插入图片描述

二、使用拖拽方式

1.设计一个拖拽容器

  <body>
    <div id="container">drag your image here</div>
  </body>

<style>
  #container {
    width: 500px;
    height: 500px;
    border: 1px solid #dfdfdf;
    margin: 0 auto;
    text-align: center;
    vertical-align: middle;
  }
</style>

在这里插入图片描述

2.拖拽文件的相关事件回调

容器的dragover事件和drop事件的默认行为是打开新页面展示,需要阻止默认行为
在drop事件回调中,获取拖拽的文件,数据存储在event.dataTransfer.files中,然后就可以调用fileReader.readAsDataURL或添加到formData中了

  const container = document.getElementById("container");
  container.addEventListener("dragover", function (event) {
    // 浏览器默认行为是打开新页面展示,需要阻止默认行为
    event.preventDefault();
  });

  container.addEventListener("drop", function (event) {
    console.log("event :>> ", event);
    event.preventDefault(); // 阻止默认的点击事件执行

    let file = event.dataTransfer.files[0];
    console.log("file :>> ", file);
    if (!file) return;

    showImg(file);
  });

  const showImg = (file) => {
    // 读取文件并转化为base64格式
    let fileReader = new FileReader();
    fileReader.readAsDataURL(file);

    fileReader.onload = function () {
      if (/^image\/[jpeg|png|gif]/.test(file.type)) {
        let img = document.createElement("img");
        img.src = fileReader.result;
        img.style.width = "500px";
        container.append(img);
      }
    };
  };

三、使用粘贴方式

1.设计一个粘贴容器

粘贴通常在一个编辑框操作,比如把div的contenteditable设置为true

<div id="container" contenteditable="true">paste your image here</div>

2.paste事件回调

粘贴的数据在event.clipboardData.files中,在容器的paste获取,代码如下:

  const container = document.getElementById("container");

  container.addEventListener("paste", function () {
    event.preventDefault();
    let file = event.clipboardData.files[0];
    console.log("file :>> ", file);
    if (!file) return;

    showImg(file);
  });

  const showImg = (file) => {
    // 读取文件并转化为base64格式
    let fileReader = new FileReader();
    fileReader.readAsDataURL(file);

    fileReader.onload = function () {
      if (/^image\/[jpeg|png|gif]/.test(file.type)) {
        let img = document.createElement("img");
        img.src = fileReader.result;
        img.style.width = "500px";
        container.append(img);
      }
    };
  };

四、总结

文件的上传常见有三种方式:选择文件、拖拽和粘贴。选择文件通常使用表单,文件的数据在form.files中,form为表单元素;拖拽的方式,文件的数据在drop事件的event.dataTransfer.files中;粘贴的方式,文件的数据在paste事件的event.clipboardData.files中;在获取上传文件的数据后,使用fileReader来读取文件数据,展示在页面上,或者添加到formData上,通过接口传递给后台。

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值