【Effective Web】文件上传

news2024/11/24 23:07:18

文章目录

  • 前言
  • 一、选择本地文件
    • 1.设计一个上传文件按钮
    • 2.FileReader读取文件内容
  • 二、使用拖拽方式
    • 1.设计一个拖拽容器
    • 2.拖拽文件的相关事件回调
  • 三、使用粘贴方式
    • 1.设计一个粘贴容器
    • 2.paste事件回调
  • 四、总结


前言

前端无法像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上,通过接口传递给后台。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1557800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「Android高级工程师」BAT大厂面试基础题集合-下-Github标星6-5K

C、 com.android.provider.contact D、 com.android.provider.contacts 11.下面关于ContentProvider描述错误的是&#xff08;&#xff09;。 A、 ContentProvider可以暴露数据 B、 ContentProvider用于实现跨程序共享数据 C、 ContentProvider不是四大组件 D、 ContentP…

【Java数据结构】关于栈的操作出栈,压栈,中缀表达式,后缀表达式,逆波兰表达式详解

&#x1f525;个人主页&#xff1a;努力学编程’ &#x1f525;内容管理&#xff1a;java数据结构 上一篇文章我们讲过了java数据结构的链表&#xff0c;对于链表我们使用了它的一些基本操作&#xff0c;完成了扑克牌小游戏的操作&#xff0c;如果你感兴趣的话&#xff0c;点…

Optimizer神经网络中各种优化器介绍

1. SGD 1.1 batch-GD 每次更新使用全部的样本&#xff0c;注意会对所有的样本取均值&#xff0c;这样每次更新的速度慢。计算量大。 1.2 SGD 每次随机取一个样本。这样更新速度更快。SGD算法在于每次只去拟合一个训练样本&#xff0c;这使得在梯度下降过程中不需去用所有训…

SpringBoot 整合Redis第1篇

SpringBoot是一个开发框架&#xff0c;Redis是一个高性能的键值存储数据库&#xff0c; 常用于缓存、会话管理、消息队列等应用场景。 定义 Redis是什么&#xff1f; 它是一个存储层级&#xff0c; 在实际项目中&#xff0c;位于关系数据库之上&#xff0c; 类似Android分为5…

(C语言)fread与fwrite详解

1. fwrite函数详解 头文件&#xff1a;stdio.h 函数有4个参数&#xff0c;只适用于文件输出流 作用&#xff1b;将从ptr中拿count个大小为size字节的数据以二进制的方式写到文件流中。返回写入成功的数目。 演示 #include <stdio.h> int main() {FILE* pf fopen(&qu…

相册清理大师-手机重复照片整理、垃圾清理软件

相册清理大师是一款超级简单实用的照片视频整理工具。通过便捷的操作手势&#xff0c;帮助你极速整理相册中的照片和视频、释放手机存储空间。 【功能简介】 向上滑动&#xff1a;删除不要的照片 向左滑动&#xff1a;切换下一张照片 向右滑动&#xff1a;返回上一张照片 整理分…

【shell】select in实现终端交互场景

文章目录 序言1. select in语句及其语法2. select in和case语句相结合3. 执行界面示例 序言 shell脚本实现简单的终端交互功能&#xff0c;根据用户不同输入执行不同功能脚本 1. select in语句及其语法 select in是shell独有的一种循环&#xff0c;非常适合终端交互场景 该语…

链表的极致——带头双向循环链表

​ 文章目录 双向带头循环链表简介&#xff1a;双向&#xff1a;带头&#xff1a;特点&#xff1a;链表带头节点的好处&#xff1a; 循环&#xff1a;特点&#xff1a;循环的好处&#xff1a; 双向带头循环链表的接口函数实现准备工作&#xff1a; 初始化链表&#xff08;头结…

C++:数据类型—布尔(12)

布尔类型代表就是真和假&#xff08;bool&#xff09; 真就是1&#xff08;true&#xff09; 假就是0&#xff08;false&#xff09; 也可以任务非0即为真 bool 直占用1个字节大小 语法&#xff1a;bool 变量名 (true | false&#xff09; 提示&#xff1a;bool在后期判断也是…

深度学习pytorch——经典卷积网络之ResNet(持续更新)

错误率前五的神经网络&#xff08;图-1&#xff09;&#xff1a; 图-1 可以很直观的看到&#xff0c;随着层数的增加Error也在逐渐降低&#xff0c;因此深度是非常重要的&#xff0c;但是学习更好的网络模型和堆叠层数一样简单吗&#xff1f;通过实现表明&#xff08;图-2&…

《自动机理论、语言和计算导论》阅读笔记:p49-p67

《自动机理论、语言和计算导论》学习第4天&#xff0c;p49-p67总结&#xff0c;总计19页。 一、技术总结 1.Deterministic Finite Automata(DFA) vs Nondeterministic Finite Automata(NFA) (1)DFA定义 (2)NFA定义 A “nonedeterministic” finite automata has the power t…

python之绘制曲线

以同一种型号的钻头&#xff0c;钻21种类型的板材&#xff0c;每种板材使用3根钻头&#xff0c;分别在钻第一个孔、2001孔、4001孔和6001孔前测量钻头外径&#xff0c;收集数据。 1、测试方法 采用激光钻径分选机测量微钻钻径以评估微钻外径磨损&#xff0c;测量从钻尖起始间…

C语言-文件

目录 1.什么是文件&#xff1f;1.1 程序文件1.2 数据文件 2.二进制文件和文本文件&#xff1f;3.文件的打开和关闭4.文件的顺序读写5.文件的随机读写5.1 fseek5.2 ftell5.3 rewind 6.文件读取结束的判定7.文件缓冲区 1.什么是文件&#xff1f; 磁盘上的文件就是文件 一般包含两…

使用pytorch构建带梯度惩罚的Wasserstein GAN(WGAN-GP)网络模型

本文为此系列的第三篇WGAN-GP&#xff0c;上一篇为DCGAN。文中仍然不会过多详细的讲解之前写过的&#xff0c;只会写WGAN-GP相对于之前版本的改进点&#xff0c;若有不懂的可以重点看第一篇比较详细。 原理 具有梯度惩罚的 Wasserstein GAN (WGAN-GP)可以解决 GAN 的一些稳定性…

caffe源码编译安装

一、前置准备 (1)vs2015 目前不要想着2019这些工具了,成功率太低了,就老老实实用vs2015吧 解决“VS2015安装包丢失或损坏“问题_vs2015跳过包会影响使用吗-CSDN博客 注意在安装vs2015过程中老是出现这个问题,其实就是缺少两个证书,安装完后就可以正常安装vs2015了,注意…

大数据面试专题 -- kafka

1、什么是消息队列&#xff1f; 是一个用于存放数据的组件&#xff0c;用于系统之间或者是模块之间的消息传递。 2、消息队列的应用场景&#xff1f; 主要是用于模块之间的解耦合、异步处理、日志处理、流量削峰 3、什么是kafka&#xff1f; kafka是一种基于订阅发布模式的…

AE——重构数字(Pytorch+mnist)

1、简介 AE&#xff08;自编码器&#xff09;由编码器和解码器组成&#xff0c;编码器将输入数据映射到潜在空间&#xff0c;解码器将潜在表示映射回原始输入空间。AE的训练目标通常是最小化重构误差&#xff0c;即尽可能地重构输入数据&#xff0c;使得解码器输出与原始输入尽…

什么是nginx正向代理和反向代理?

什么是代理&#xff1f; 代理(Proxy), 简单理解就是自己做不了的事情或实现不了的功能&#xff0c;委托别人去做。 什么是正向代理&#xff1f; 在nginx中&#xff0c;正向代理指委托者是客户端&#xff0c;即被代理的对象是客户端 在这幅图中&#xff0c;由于左边内网中…

如何解决kafka rebalance导致的暂时性不能消费数据问题

文章目录 背景思考答案排它故障转移共享 背景 之前在review同组其它业务的时候&#xff0c;发现竟然把kafka去掉了&#xff0c;问了下原因&#xff0c;有一个单独的服务&#xff0c;我们可以把它称为agent&#xff0c;就是这个服务是动态扩缩容的&#xff0c;会采集一些指标&a…

k8s的pod访问service的方式

背景 在k8s中容器访问某个service服务时有两种方式&#xff0c;一种是把每个要访问的service的ip注入到客户端pod的环境变量中&#xff0c;另一种是客户端pod先通过DNS服务器查找对应service的ip地址&#xff0c;然后在通过这个service ip地址访问对应的service服务 pod客户端…