问题整理

最近做的项目是要实现多张上传图片的功能,可以删除图片,选中多张图片并重新上传,在实践过程中遇到了以下问题:

  1. 图片如何更好的布局以及删除及选中效果如何实现
  2. 利用<input type="file">上传图片时,上传同一张图片失效
  3. 上传多张图片时,如何读取多张上传文件
  4. <input type="file">同时添加单击和双击事件,单击事件触发两次
  5. 利用get方式传递参数,中文乱码问题

1.图片效果


为实现图1中的效果,需要解决两个问题:第一个是如何进行图片布局;第二个是如何实现删除及选中效果。

  • 图片布局
    对于图片布局,利用<img><span><input>这三个标签是可以实现图1中的样式的,但是需要进行样式调整,而且图片多张进行排列的时候间距及布局不好把握。
    在插入图片方面,HTML5提供了<figure>标签来插入图片,并提供<figcaption>来描述图片。
<figure><figcaption>图片描述:<input tppe="text"></input></figcaption>
</figure>
  • 删除及选中效果
    在插件样式方面,boostrap提供了丰富的插件样式,可以实现图1中需要的删除及选中效果。
    需要注意的是,删除的叉号标志需要定位到图片的右上角,可以利用绝对定位的方式来实现。选中效果则需要以下三步来完成:将对号定位到图片中间位置,为对号添加蓝色圆形填充,将对号定位到圆形填充的中央。
position: absolute;
top: 0;
left: 0;
right: 0;
margin: auto;border: 2px solid blue;
border-radius: 50%;text-aligh: center;
line-height: 80px;

2.上传同一张图片

利用<input type="file">上传图片时,当选中了一张图片点击取消或者选中图片并打开,然后删除该图片,再选中刚刚的图片是无法出发onChange或onClick事件的。
这种现象产生的原因是上传文件的时候,会将当前的文件路径保存在<input>的value中,点击取消其value值不会改变,所以导致第二次上传同一张图片的时候,是同一个value,因此无法触发函数。

  • 解决办法
    a. 删除原来的<input>框,重新生成一个<input>框,并绑定onChange事件。
    b. 每次上传文件之后,手动修改input框的value值。

在开发过程中,要尽量避免直接操纵DOM元素的方法,因此对于以上两种解决办法,倾向于采取第二种。
<input>框中,绑定ref,用于获取DOM元素。

<input ref={input => {this.input = input;}}>

然后,在上传文件后,将value值清空。

this.input.value = '';

3.读取多张上传文件

利用<input type="file">上传图片,如果添加了"webkitdirectory"属性,则可以一次上传多张图片,此时涉及到如何读取多张图片并展示。
首先,需要获取文件信息,<input>会将上传的文件信息以数组的形式保存在event中,可以通过event.target.files来获取文件信息。
然后,new一个FileReader对象来读取文件,FileReader主要有3个方法如下列表展示。

方法名 参数 描述
readAsBinaryString file 将文件读取为二进制码
readAsDataURL file 将文件读取为 DataURL
readAsText file, [encoding] 将文件读取为文本

对于图像的读取,选择readAsDataURL方法,读取读像的base64编码,用于图像的展示。当文件读取成功后,需调用FileReader的onload方法来进行图片读取成功之后的操作。

onChange = e => {let $input = e.target;const files = $input.files;const reader = new FileReader();reader.readAsDataURL(files[0]);reader.onload = () => {img.push(this.result); //图像base64编码保存到数组中}

需要注意的是,当一次上传多张图片时,需要将files数组中的多个值全部读出来,最容易想到的办法是外层加一个for循环,每次循环读取。但是这样没法全部按顺序读取图片,其原因是reader.onload()事件是异步触发的。
可以通过递归调用读取图片函数来解决这个问题:

onChange = e => {let $input = e.target;const files = $input.files;this.loadImgs(files, 0);
}
loadImgs = (files, index) => {const _this = this;if (index !== files.length){const reader = new FileReader();reader.readAsDataURL(files[i]);reader.onload = () => {img.push(this.result); //图像base64编码保存到数组中index++;_this.loadImgs(files, index); //递归调用读取函数}}
}

4.阻止单击事件

项目中有这样一个应用场景,单击图片呈选中状态,双击图片需要展示图片的原图。首先想到的是通过给图片绑定单击事件和双击事件来出发选中及展示原图。
<img src={content} onClick={this.checkImage} onDoubleClick={this.showImage}>

但是这样存在的问题是双击图片时,会先触发单击事件,然后再出发双击事件,而我需要的是双击时只触发双击事件。这样的话就需要给单击事件一个延迟时间,在时间范围内点击图片不会出发单击事件,也就解决了这个问题。

const timer = null;
checkImage = () => {clearTimeout(timer);timer = setTimeout(function(){//do something},250);
}
showImage = () => {clearTimeout(timer);// do something
}

值得注意的是,在setTimeout定时器中,this指针会获取不到,因此如果需要在定时器函数中用到this指针,需要实现声明一个新的变量const _this=this;来存储this指针。

5.get传参问题

通过window.open()打开链接的时候,需要将参数传到新页面,在新页面需要接收这个参数并进行处理。这个时候可以通过window.location这个对象的属性来接收并处理参数。该对象包含的属性有以下几种:

属性 描述
hash 从井号 (#) 开始的 URL(锚)
host 主机名和当前 URL 的端口号
hostname 当前 URL 的主机名
href 完整的 URL
pathname 当前 URL 的路径部分
port 当前 URL 的端口号
protocol 当前 URL 的协议
search 从问号 (?) 开始的 URL(查询部分)


当利用window.location.search来获取参数的时候,需要注意两点:
a. 需要用正则找到需要的参数。
window.location.search.substring(1).split("=")[1],如果有多个参数,还需要利用“&”进一步分割。
b. 参数中存在中文时会被编码。
“./main.html?user=小明"该链接中存在中文字符,如果不解码直接接收会接收到一串编码,而不是想要的中文参数。因此,需要利用decodeURIComponent()进行解码。
decodeURIComponent(window.location.search.substring(1).split("=")[1])

以上就是对最近遇到的问题的整理。

前端图片上传问题整理相关推荐

  1. anguarjs 上传图片预览_前端图片上传那些事儿

    本文转自:掘金 作者:chess 前言 本文讲的图片上传,主要是针对上传头像的.大家都知道,上传头像一般都会分成以下 4 个步骤: 选择图片 -> 预览图片 -> 裁剪图片 -> 上 ...

  2. 前端图片上传那些事儿

    本文讲的图片上传,主要是针对上传头像的.大家都知道,上传头像一般都会分成以下 4 个步骤: 选择图片 -> 预览图片 -> 裁剪图片 -> 上传图片 接下来,就详细的介绍每个步骤具体 ...

  3. 前端图片上传并且裁切

    本文讲的图片上传,主要是针对上传头像的.大家都知道,上传头像一般都会分成以下 4 个步骤: 选择图片 -> 预览图片 -> 裁剪图片  -> 上传图片 接下来,就详细的介绍每个步骤具 ...

  4. 前端图片上传发现图片倒置解决方案 图片镜像效果实现

    图片倒置解决方案 前端使用canvas将颠倒的图片进行旋转矫正 图片镜像效果实现 通过scale调整方向即可. scale(scaleX, scaleY):通过在 x 轴乘以 scaleX.在 y 轴 ...

  5. java的图片上传与前端展示实例(Servlet+Jsp)

    java的图片上传与前端展示实例(Servlet+Jsp) 内容前瞻 1.关于路径 2.前端图片上传与展示 3.后台获取并保存 环境 1.前端jsp 2.服务器tomcat 3.服务端servlet ...

  6. mavon-editor编辑器与图片上传

    mavon-editor编辑器与图片上传 图片上传是一个常用的功能,今天我们来实现基于Vue的Markdown编辑器--mavon-editor的图片上传功能. 一.安装与引入 1. 首先在命令行安装 ...

  7. 【Upload oss图片 上传失败】

    目录 前言: 描述: 也可以单独创建一个  类: 前言: 今天摸鱼的时候遇见一个文件上传失败的问题 所以记录一下, giao 描述: 因为那个前端图片上传格式有优化了,图片变大了,上传小文件的时候没发 ...

  8. php layui ajax多图上传,Laravel+Layer实现图片上传功能(整理篇)

    ♩ 背景 昨天在自己的 Laravel5.5 框架项目中,希望集成 Layer 的图片上传功能 但是在 ajax(POST) 提交请求时,一直显示 500 报错 ♪ 分析 ⒈ 问题所在 最后将核心代码 ...

  9. html显示数据库图片django,django将图片上传数据库后在前端显式的方法

    1.使用ImageField先安装pillow模块 pip install pillow 2.在app的models中设置 class Image(models.Model): pic_name=mo ...

  10. alert()的功能_前端实现简单的图片上传小图预览功能

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...

最新文章

  1. 用C++/CLI搭建C++和C#之间的桥梁(一)—— 简介
  2. laravel实现多数据源配置和读写分离
  3. 周报速递丨北交所 SaaS 首股将出;央行等印发《金融标准化“十四五”发展规划》
  4. C# 算法题系列(一) 两数之和、无重复字符的最长子串
  5. 嵌入式系统中看门狗概述。。。
  6. Flask项目--注册
  7. [think]需求从来就没变过,变的是我们对需求的理解
  8. ReactNative字体大小不随系统字体大小变化而变化
  9. 8选1的多路选择器c语言代码,八选一数据选择器的VHDL程序
  10. 了解H.264(AVC)的你,知不知道什么是SVC?
  11. 学习编程语言的第一步,认识什么是计算机!!!
  12. 自己手写的一个关于中英文切换时间的工具类
  13. DevOps团队绩效考核重点
  14. FusionConpute虚拟机的发放与管理
  15. Linux基本指令总结
  16. 【每日新闻】微软亚洲研究院院长洪小文:今天的AI只是一个黑盒 | 北京市政交通一卡通充值今起可在线领取电子发票...
  17. 生化危机2重制版 小笔记
  18. 从文化地理看三国演义
  19. 凡灵物语-浪漫仙侠回合手游
  20. spark dataframe和dataSet用电影点评数据实战

热门文章

  1. OC load 和 initialize 方法
  2. vue yaml代码编辑器组件
  3. 基于jsp+mysql+Spring+SpringMVC+mybatis的高速公路收费管理系统
  4. Spring Boot 2.1.2配置文件参考配置项官方谷歌翻译版本
  5. mysql normsinv,在MySQL中实现NORMSINV函数
  6. C++语法学习笔记十四:派生类-调用顺序-访问等级-函数遮蔽
  7. IOS开发-苹果开发者中心 提示 edit phone number
  8. python数字转对应中文_python英文数字到中文数字的转换
  9. Docker 配置国内镜像加速器
  10. 微软电脑管家登陆微软商店 简单无打扰 支持杀毒和垃圾清理等