前言

今天我们聊一聊图片上传,单张Or多张 ,如今,各大图片上传插件数不胜数,例如:Jquery的 verupload.js,jQuery File Upload、Uploadify、jQuery.filter等等。But。上面说到的这些插件,今天我们不谈,我们来看一看使用HTML5中的FileReader 如何实现 图片的单张及多张预览、删除、上传等功能。

先看下实现后的效果如下:

实现

前端部分

这块是用户点击按钮 其中我们最重要的一句话是input type=file 和给了一个multiple属性,可以满足多张图片上传

<div class="form-group form-row">
<label class="col-sm-2 control-label uText">俱乐部相册</label><div class="row">
<div class="col-xs-10 col-sm-8 mTop5">
<label title="上传俱乐部相册" for="ClubImagesUpload" id="btnClubImg" class="col-sm-2"> <input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple"> <img src="/Images/registerNewSite/btn_addimg.png" class="addImg"/>
</label>
</div>
</div></div>

下面这块区域是用于图片预览的

<div class="form-group form-row" id="preViewMore"><div class="row">
<div class="col-xs-9">
<div id="clubInputImagePreview" class="col-sm-9 img-preview img-preview-sm"></div>
</div>
</div></div>

样式部分

什么?连样式你都要看,还有没有人性(苦笑脸)

Js部分

首先我们分析下上面的html,我们用一个label把input和一个img标签包起来了,我们希望点击效果图那个+号图片,就能弹出选择相片的对话框,所以,我们需要先给label来一个点击事件:

$("#btnClubImg").click(function() {
//TODO Something
});

接着我们再看,因为我们是要获取上传的文件,而我们的文件主要是在input上,所以,我们先将input标签获取到:

$("#btnClubImg").click(function() {
var $input = $("#ClubImagesUpload");
console.log($input);//打印当前元素
});

我们将当前input元素标签打印出来看看是个什么东东

我们展开第一项会发现files里面length长度是0

好,我们继续分析,因为我们想要能当input框改变的时候,说简单点 就是有选择到文件的时候,我们能获取到当前选择的文件,这个和获取input框文字输入是一样的道理,所以,经过分析,我们知道需要给input标签加一个change事件:

 $("#btnClubImg").click(function() {
var $input = $("#ClubImagesUpload");
console.log($input);
$input.on("change", function () {
console.log(this);//打印改变后的当前元素
});
});

让我们来瞄一眼,获取到改变后的input元素里面有些啥东东:

这里很清楚得可以看到,我们获取到了选择的图片,包括有最后修改事件,图片名称,大小以及图片类型(有了文件类型,我们就可以判断当前用户选择的是否是图片不是吗(斜眼笑))

同样,这是单个文件的, 如果是多个文件,就会有多个file

接着往下看,通过打印输出我们可以看到,我们再input 标签的files元素上已经拿到了我们想要的文件信息,我们只需要获取它们就行了:

 var files = this.files;
var length = files.length;

这样,我们就可以获取到所有文件,以及文件的个数,那这里问题来了,我们如果是选择多个文件,如果将其依次输出并展示到页面上呢?

看到上面标注的四个字,脑袋中有没有闪现出两个字呢?循环

 $.each(files, function (key, value) {
//TOTO Something
});

通过将上面得到的files 循环,我们可以依次得到每个文件的信息。这样,你就不仅可以将其依次输出,如果你愿意,你还可以将其送上天~

var fileReader = new FileReader();//实例化一个FileReader对象
var file_ = files[key];//获取当前文件
if (/^image\/\w+$/.test(file_.type)) {//将当前文件进行正则匹配,看是否是选择的图片
fileReader.onload = function() {//当读取操作完成时调用 }
}

有必要延伸下FileReader的知识点:

FileReader主要用于将文件内容读入内存,通过一系列异步接口,可以在主线程中访问本地文件。

使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要处理的文件或数据。

回到主题,我们已经能够得到文件并且得到返回,所以此时,我们只需要展示返回的结果就行了

 $("#clubInputImagePreview").css("background-image", "url(" + this.result + ")");

我们将其this.result打印出来看看是个什么东东:

不言而喻,是将图片转换成了Base64的数据格式。最后,我们调用 readAsDataURL 读取文件内容,将其用data:url字符串表示出来

fileReader.readAsDataURL(value);

这样,你就可以得到一个简易的图片上传的Demo了,但是并不是最终的,因为你还需要加很多业务进去。比如:得到一张预览图片后,当前标签会被占用,如果下次循环进来,直接使用原标签,肯定会将之前的图片替换,那这肯定不是我们想要的效果,

我们希望是能依次展示,而不是替换展示。所以,我们还需要做一些处理:

 $("#clubInputImagePreview").css("background-image", "url(" + this.result + ")");

//使用apend再当前元素下追加一个子节点
$("#clubInputImagePreview") .append("<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage' id='ImgRemove' />"); //使用after 向当前兄弟节点 追加一个同级节点
$("#clubInputImagePreview").after( "<div id='clubInputImagePreview1' class='col-sm-9 img-preview img-preview-sm delImg' ></div>");

然后我们追加的删除图片,也需要给其点击事件,让我们的当前预览区域消失:

$("#ImgRemove").click(function () {
$(this).parent().remove();
});

最后,你会发现结果还不是我们想要的,那是因为 当前ID还在,所以无法进行下一步操作,而我们只需要将当前元素的Id Remove掉,然后新增一个同ID的元素,这样浏览器就会认为这是一个新的元素:

 $input.removeAttr("id");
var newInput ='<input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple">';
$(this).append($(newInput));

最后完整JS代码如下:

  var intP = 0;
$("#btnClubImg").click(function() {
var $input = $("#ClubImagesUpload");
// console.log($input);
$input.on("change",
function () {
// console.log(this);
var files = this.files;
var length = files.length;
if (intP > 8) {
layer.msg('图片不能再多了~', {});
return;
} $.each(files,
function (key, value) {
var fileReader = new FileReader();
var file_ = files[key];
if (/^image\/\w+$/.test(file_.type)) {
fileReader.onload = function() {
if (intP > 8) {
layer.msg('图片不能再多了~', {});
return;
}
if (key == 0 && intP == 0) {
console.log(this.result);
$("#clubInputImagePreview").css("background-image", "url(" + this.result + ")"); $("#clubInputImagePreview")
.append(
"<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage' id='ImgRemove' />"); $("#clubInputImagePreview").after(
"<div id='clubInputImagePreview1' class='col-sm-9 img-preview img-preview-sm delImg'></div>");
} else {
$("#clubInputImagePreview" + parseInt(intP) + "").css("background-image",
"url(" + this.result + ")"); $("#clubInputImagePreview" + parseInt(intP) + "").append(
"<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage' id='ImgRemove" +
parseInt(parseInt(1) + parseInt(intP)) +"' />"); $("#clubInputImagePreview" + parseInt(intP) + "").after(
"<div id='clubInputImagePreview" +
parseInt(parseInt(1) + parseInt(intP)) +
"'class='col-sm-9 img-preview img-preview-sm delImg' ></div>");
}
if (key == 0 && intP == 0) {
$("#ImgRemove").click(function () {
$(this).parent().remove();
});
} else {
$("#ImgRemove" + parseInt(parseInt(1) + parseInt(intP)) + "").click(function () {
$(this).parent().remove();
});
} intP += parseInt(1);
};
fileReader.readAsDataURL(value);
} else {
layer.msg("格式错误<br/>请选择一个图片文件");
}
}); }); $input.removeAttr("id");
var newInput =
'<input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple">'; $(this).append($(newInput)); });

下一篇,将讲述 如何将前端得到的多个File ,存入进数据库,后端是.NET Core,敬请期待吧~

H5单张、多张图片上传的更多相关文章

  1. Volley-XUtils-OkHttp三种方式实现单张多张图片上传

    OkHttp可以作为Volley底层传输协议,速度更快,传大量图片建议使用.OkHttp更多功能请看OkHttp的使用 xUtils 支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更 ...

  2. js移动端/H5同时选择多张图片上传并使用canvas压缩图片

    最近在做一个H5的项目,里边涉及到拍照上传图片的功能以及识别图片的功能,这里对识别图片的功能不做赘述,不属本文范畴.我在做完并上线项目后,同事跟我提了一个要求是可不可以同时选择多张图片上传,我做的时候 ...

  3. JavaScript实现多张图片上传功能

    今天闲着没事,把之前的多张图片上传代码整理了下. 页面主要代码: <div class="upBox upBox2"> <div class="d1&q ...

  4. 微信小程序多张图片上传

    微信小程序上传图片每次只能上传一张,所有很多朋友就会问想要多张图片上传怎么办? 首先,我们来看一看wx.chooseImage(object)和wx.uploadFile(OBJECT)这两个个api ...

  5. UMeditor控制多张图片上传顺序

    多张图片上传的顺序,受到用户使用习惯.插件上传和插件插入页面顺序的影响. 估计是考虑到上传性能,官方没有提供UMeditor控制展示顺序的配置.在上传过程中,用户点击拖动的第一张图片,将作为文件数组中 ...

  6. nodejs-使用multer实现多张图片上传,express搭建脚手架

    nodejs-使用multer实现多张图片上传,express搭建脚手架 在工作中,我们经常会看到用户有多张图片上传,并且预览展示的需求.那么在具体实现中又该怎么做呢? 本实例需要nodejs基础,本 ...

  7. 用原生JS实现多张图片上传及预览功能(兼容IE8)

    最近需要做一个图片上传预览的功能(兼容IE8-11.chrome.firefox等浏览器),网上现有的文件上传组件(如webuploader)总是会遇到一些兼容性问题.于是我参考了一些博文(链接找不到 ...

  8. Spring Boot MVC 单张图片和多张图片上传 和通用文件下载

    @Autowired private ServerConfig serverConfig; /** * 通用下载请求 * * @param fileName 文件名称 * @param delete ...

  9. 基于HTML5的多张图片上传

    图片上传之前也有写过demo,不过是单张上传的,最近有个业务需求是需要多张上传的,于是乎从新改写了一下 HTML结构: 1 2 3 4 <div class="container&qu ...

随机推荐

  1. YUV420格式解析

    一般的的YUV420图像格式实际上是Y'UV,420指的是其在Y U V上面的采样率.在YUV420的格式中,首先存储每一个像素的Y'值,然后跟着存储的是每2*2方阵采样一次的U值,最后存储的是每2* ...

  2. python---haproxy---文件操作

    haproxy 文件操作,操作属于简单操作,不复杂 # -*- coding:utf-8 -*- # LC def search(*args): #查找Haproxy文件中的服务器 list1 = [ ...

  3. Dubbo配置引发的一个问题--- Duplicate spring bean id

    1.原因 因项目业务需要,要调用RPC框架,项目原本已经依赖了很多RPC接口需要启动时加载,所以准备做成启动时不预加载. 就是在配置的时候加上check=false. 官方文档解释的作用,就是Dubb ...

  4. JavaScript(二、BOM 浏览器对象模型)

    一.BOM是什么 BOM是browser object model的缩写,简称浏览器对象模型 BOM提供了独立于内容而与浏览器窗口进行交互的对象 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心 ...

  5. 微信授权、获取用户openid-纯前端实现——jsonp跨域访问返回json数据会报错的纯前端解决办法

    近来,倒霉的后台跟我说让我拿个openid做微信支付使用,寻思很简单,开始干活. 首先引导用户打开如下链接,只需要将appid修改为自己的就可以,redirect_url写你的重定向url https ...

  6. Spring MVC 文件上传 & 文件下载

    索引: 开源Spring解决方案--lm.solution 参看代码 GitHub: pom.xml WebConfig.java index.jsp upload.jsp FileUploadCon ...

  7. Activity的运行过程

    今天看到了这个关于Activity的过程这个方面的知识,之前我其实也是做过安卓项目的,也是有安卓开发的一定经验的,但是我发现之前似乎是知其然,而不知其所以然,之前来说只知道activity里的onCr ...

  8. WPF 定义Command

    直接上代码: public class LoginDelegateCommand : ICommand { private Action _execute; private Predicate< ...

  9. JFrame图形界面 ----鼠标消息

    #开始 不管是什么GUI 按钮的存在都是必不可少的而且还会有很多奇怪的按钮 #代码 package window; import java.awt.Container; import java.awt ...

  10. Whitelabel Error Page 专题

    Spring boot为错误视图提供了如下错误属性:timestamp:错误发生的时间status:HTTP状态码error:错误原因exception:异常的类名message:异常消息(如果这个错 ...