闲来无事,突然想用原生来实现图片的多图上传。

一、效果图大致如下:

1、上传时可以选择多图

2、上传之后缩略图下过图如下:

3、点击缩略图,大图展示当前所点击的图片,并可以左右滑动查看其它的缩略图对应的大图。效果如下:

4、点击删除,弹出是否要删除的弹框,点击确定后,删除。效果图如下:

二、要求

1、限制图片的张数(4张)

2、限制单个图片的大小(1M)

3、支持拖拽上传

4、上传后显示小图预览

5、点击小图进行大图预览

6、实现agax上传

三、所需插件

1、由于时间原因,页面布局依赖于bootstrap

2、滚动插件用的swiper.js

3、弹框差价layer

四、页面布局

4-1、缩略效果图如下:

4-2、缩略图的HTML代码如下:

<form action="post" class="vaildform fmreset" enctype="multipartform-data">
<div class="form-group clearfix">
<label class="col-lg-2 col-md-2 col-sm-2 control-label" for="userName">图册</label>
<div class="col-lg-10 col-md-10 col-sm-10 clearfix">
<!-- 图片展示 -->
<div class="atlas-container pull-left clearfix">
<div class="atlas-content">
<i class="js-del-img fm-icon ion-close-circled"></i>
<div class="img-container">
<img src=/assets/images/logbg.png alt="图册" />
</div>
</div>
</div>
<!-- 图片上传 -->
<div class="upload-container pull-left">
<input id="fileUpload" type="file" name="" value="" multiple accept="image/png,image/gif,image/jpg,image/jpeg" />
<div class="fileUpload"></div>
</div>
</div>
</div>
<div class="form-group clearfix">
<label class="col-lg-2 col-md-2 col-sm-2 control-label" for="userName"></label>
<div class="col-lg-10 col-md-10 col-sm-10">
<a id="js-submit" href="javascript:;" class="btn btn-primary">提交</a>
</div>
</div>
</form>

我们知道form表单要实现文件上传 form标签上必须有“enctype="multipartform-data"”这个属性,上传类型为post,实现文件上传的空间就是

<input id="fileUpload" type="file" name="" value=""/>

 1、这是一句图片文件上传的控件,可我们想要实现图片上传,就要限制文件的类型,使用属性“accept”,accept="image/png,image/gif,image/jpg,image/jpeg",这句话用来限制图片的类型,这里列举的类型不多,大家可以根据自己的需要调整。当然你也可以写成“accept="image/*"”,不过这样写的话,点击上传,出现选择文件的框会出现很慢。

 2、有的同学会发现,这样写只能一次上传一张图片,大家别急,当我们给这个控件加上“multiple ”这个属性后就能实现多图上传啦。详细上传控件如下:

 <input id="fileUpload" type="file" name="" value="" multiple accept="image/png,image/gif,image/jpg,image/jpeg"/>

4-3、缩略图的css布局如下:

// 图册容器
.atlas-container{}
.atlas-container .atlas-content{
margin-left:15px;
float: left;
position: relative;
}
.atlas-container .atlas-content .img-container{
width:115px;
height:115px;
background:@white;
padding:5px;
border: 1px solid #e5e5e5;
border-radius: 3px;
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
-webkit-box-pack: center; /*子元素水平居中*/
-moz-justify-content: center; /*子元素水平居中*/
-webkit-justify-content: center;/*子元素水平居中*/
justify-content: center; /*子元素水平居中*/
-webkit-box-align: center;/*子元素交叉轴对齐方式*/
-moz-align-items: center;/*子元素交叉轴对齐方式*/
-webkit-align-items: center;/*子元素交叉轴对齐方式*/
align-items: center;/*子元素交叉轴对齐方式*/
cursor:pointer;
position:relative;
}
.atlas-container .atlas-content .img-container img{
max-width:100%;
max-height:100%;
display:block;
}
.atlas-container .atlas-content .fm-icon{
cursor:pointer;
font-size: 16px;
right: -11px;
top: -14px;
position: absolute;
color: rgba(0,0,0,.5);
z-index:;
}
.atlas-container .atlas-content .fm-icon:hover{color:rgba(0,0,0,.7);}
// 上传容器
.upload-container{
width:120px;
height:120px;
margin-left:15px;
overflow:hidden;
position: relative;
}
#fileUpload{
width:100%;
height:100%;
top:;
left:;
right:;
bottom:;
opacity:;
cursor:pointer;
position:absolute;
z-index:;
}
.upload-container .fileUpload{
width:100%;
height:100%;
cursor:pointer;
background:@white;
border: 1px solid #e5e5e5;
border-radius: 3px;
-o-border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
position: relative;
}
.upload-container .fileUpload:before{
content:"";
width:32px;
height:2px;
background:#cbcbcb;
top:50%;
left:50%;
margin-left:-16px;
margin-top:-1px;
position: absolute;
}
.upload-container .fileUpload:after{
content:"";
width:2px;
height:32px;
background:#cbcbcb;
top:50%;
left:50%;
margin-left:-1px;
margin-top:-16px;
position: absolute;
}

4-4、大图HTML布局如下:

<div class="picture-preview">
<div class="swiper-container">
<!-- 轮播盒子 -->
<div class="swiper-wrapper">
</div>
<!-- 前进后退按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- 分页器 -->
<div class="swiper-pagination"></div>
</div>
</div>

4-5、大图对应的css样式如下:

// 大图预览
.picture-preview{display:none;max-height:100%;}
.picture-preview .preview-container{
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
-webkit-box-pack: center; /*子元素水平居中*/
-moz-justify-content: center; /*子元素水平居中*/
-webkit-justify-content: center;/*子元素水平居中*/
justify-content: center; /*子元素水平居中*/
-webkit-box-align: center;/*子元素交叉轴对齐方式*/
-moz-align-items: center;/*子元素交叉轴对齐方式*/
-webkit-align-items: center;/*子元素交叉轴对齐方式*/
align-items: center;/*子元素交叉轴对齐方式*/
height:100%;
}
.picture-preview .preview-container img{
max-width:100%;
max-height:100%;
display:block;
}

5、js逻辑编写

随着和html5的普及,file的各种API越来越强大,HTML5 file 的API返回了很多有用的图片信息,我们可以利用这些信息来实现图片的预览效果。

1、我们可以在控制台上打印出我们要上传的图片信息:

里面包含“length”->当前上传的图片个数;"lastModified"->最后的更改;“name”->图片的名字;"size"->图片的大小,"type"->图片的类型

5-1,图片上传功能

1、缩略图上传

imgUpload:function(){
var fileUpload = document.getElementById("fileUpload"); //得到图片的上传控件
fileUpload.addEventListener('change',uploadFile,false); // 监听上传控件
var length=0; // 监听图片的个数
var size=0; // 监听单个图片的大小
var url=''; // 用来保存图片的位置
var atlasContent = $('.atlas-container').find('.atlas-content');
if(atlasContent){
length = atlasContent.length;
mainCtrl.picInit(); // 初始化大图容器
}
// 图片上传事件
function uploadFile(){
var files = this.files; // 得到files
var lengthN =parseInt(files.length); // 保存当前上传的个数
length+=lengthN; // 图片个数
if(length>4){ // 图片上传超过四个
layer.msg('图片个数不能超过4个',function(){
fileUpload.value=''; // 清空当前的上传控件,
length=length-lengthN; // 图片未添加,length回到原先的状态
});
return; // 终止程序
} for(var i=0;i<lengthN;i++){ // 遍历当前的上传的个数,
size= files[i].size; // 得到单个图片的大小
if(size>1024*1024){ // 单个图片大于1M
layer.msg(files[i].name+'这张图片大于1M',function(){ // 提示哪张图片的大小超出1M
fileUpload.value=''; // 清空当前的上传控件,
length=length-lengthN; // 图片未添加,length回到原先的状态
});
return;
}else{
var html=''; // 缩略图
var bigHtml=''; // 大图 // 终止程序
url = window.URL.createObjectURL(files[i]); // 方法会根据传入的参数创建一个指向该参数对象的URL. 这个URL的生命仅存在于它被创建的这个文档里. 新的对象URL指向执行的File对象或者是Blob对象.
html+='<div class="atlas-content">';
html+='<i class="js-del-img fm-icon ion-close-circled"></i>';
html+='<div class="img-container" data-name="'+files[i].name+'">';
html+='<img src='+url+' alt="图册"/>';
html+='</div>';
html+='</div>';
bigHtml+='<div class="swiper-slide">';
bigHtml+='<div class="preview-container">';
bigHtml+='<img src='+url+' alt="图册"/>';
bigHtml+='</div>';
bigHtml+='</div>';
$('.atlas-container').append(html); // 将缩略图片写入
$('.picture-preview .swiper-wrapper').append(bigHtml); // 将大图写入
}
} if(length===4){
$('.upload-container').hide(); // 图片上传控件隐藏
} // 删除图片
$('.atlas-container').on('click','.js-del-img',function(){
var index = $(this).index();
var _this = this;
var picName = $(this).next('.img-container').data('name');
layer.confirm('确定删除 '+picName+' 这张图片?',
{
btn: ['确定','取消'] //按钮
},
function(){
$(_this).parent('.atlas-content').remove(); // 缩列图删除
mainCtrl.picInit(); // 重新渲染
length--;
if(length<0){length=0;}
$('.upload-container').show(); // 图片上传控件显示
layer.msg('删除成功', {icon: 1,time:1000});
},
function(index){
layer.close(index);
}
);
})
};
},
// 大图初始化
picInit:function(){
var thumbnailObj = $('.atlas-container').find('.atlas-content');
var picLength = thumbnailObj.length;
var picHtml='';
var thumbnailImgSrc='';
for(var i=0;i<picLength;i++){
thumbnailImgSrc = thumbnailObj.eq(i).find('img').attr('src');
picHtml+='<div class="swiper-slide">';
picHtml+='<div class="preview-container">';
picHtml+='<img src='+thumbnailImgSrc+' alt="图册"/>';
picHtml+='</div>';
picHtml+='</div>';
}
$('.picture-preview .swiper-wrapper').empty().append(picHtml);
},

注意:由于大图和小图不在同一个容器里,所以在缩略图改变的时候,要及时更新大图的容器

2、点击缩略图初始化swiper插件(注意:一定要在layer的success函数里初始化,不然容易swiper比layer初始化快,swiper就不起作用了)

picturePreview:function(){
$('.atlas-container').on('click','.img-container',function(){
var key = $(this).parent('.atlas-content').index(); // 保存当前小图的索引值
layer.open({
type: 1,
shade: true,
shadeClose:true,
area: ['100%', '100%'],
scrollbar:false,
title: ['相册大图预览', 'font-size:22px;text-align:center'],
content: $('.picture-preview'), //捕获的元素,注意:最好该指定的元素要存放在body最外层,否则可能被其它的相对元素所影响
success:function(){
mainCtrl.pictureCarousel(key);
},
cancel: function(index){
layer.close(index);
}
});
});
},

3、swiper滚动初始化

pictureCarousel:function(key){
$('.picture-preview .swiper-container .swiper-wrapper').height($(window).height()-48); // 42是弹框标题的高度
$(window).resize(function(){ // 监听浏览器大小的变化
$('.picture-preview .swiper-container .swiper-wrapper').height($(window).height()-48); // 42是弹框标题的高度
})
var picSwiper = new Swiper('.picture-preview .swiper-container', {
pagination : '.picture-preview .swiper-pagination',
initialSlide:key, // 起始页设置
slidesPerView: 1, // 只显示1个
paginationClickable:true, // 点击分页器的指示点分页器会控制Swiper切换
autoplay: 2000, // 可选选项,自动滑动
autoplayDisableOnInteraction:false, // 用户操作后还可以自动切换
grabCursor:true, // 小手形状
paginationClickable:true, // 分页器
lazyLoading:true, // 懒加载
loop:true, // 循环
// prevButton:'.picture-preview .swiper-button-prev',
// nextButton:'.picture-preview .swiper-button-next',
});
$('.picture-preview .swiper-container').hover(function(){
picSwiper.stopAutoplay(); // 鼠标移入禁止自动切换
},function(){
picSwiper.startAutoplay(); // 鼠标移出开启自动切换
})
$('.picture-preview .swiper-button-prev').click(function(){ // 上一页
picSwiper.slidePrev();
})
$('.picture-preview .swiper-button-next').click(function(){ // 下一页
picSwiper.slideNext();
})
},

后续:
4-5,拖拽上传

4-6、图片编辑剪切

4-7、图片编辑旋转

4-8、图片编辑大小

4-9、显示图片上传进度

4-10、终止、开始图片上传

HTML5 原生API input file 来实现多图上传,并大图预览的更多相关文章

  1. 根目录97 <input file>标签,把图片上传到服务器(跟增删改查一起实现)

    首先来个简单的html页面: enctype="multipart/form-data" encoding="multipart/form-data" acti ...

  2. HTML5文件上传前本地预览

    HTML5之FileReader的使用 HTML5定义了FileReader作为文件API的重要成员用于读取文件,根据W3C的定义,FileReader接口提供了读取文件的方法和包含读取结果的事件模型 ...

  3. file图片上传之前先预览

    链接:https://www.cnblogs.com/tandaxia/p/5125275.html 记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<inp ...

  4. vue给input file绑定函数获取当前上传的对象

    HTML <input type="file" @change="tirggerFile($event)"> JS(vue-methods) tir ...

  5. 上传图片,多图上传,预览功能,js原生无依赖

    最近很好奇前端的文件上传功能,因为公司要求做一个支持图片预览的图片上传插件,所以自己搜了很多相关的插件,虽然功能很多,但有些地方不能根据公司的想法去修改,而且需要依赖jQuery或Bootstrap库 ...

  6. 怎么样通过php使用html5实现多文件上传?(php多图上传)

    <!DOCTYPE html><html lang="zh-cn"> <head> <meta charset="utf-8&q ...

  7. HTML5 多图上传

    HTML5 多图上传 时间 2014-06-05 16:06:29  月小升博客 原文  http://java-er.com/blog/html5-many-image-upload/ 主题 HTM ...

  8. 利用html5的FormData对象实现多图上传

    <html> <head> <title>FormData多图上传演示</title> </head> <body> <a ...

  9. struts2 s:file标签使用及文件上传例子

      <s:form action="uploadaction" method="post" enctype="multipart/form-da ...

随机推荐

  1. iview table的render()函数的用法

    语法:render:(h,params)=>{} render:(h,params) => { return h(" 定义的元素 ",{ 元素的性质 }," ...

  2. IIS配置Windows防火墙允许外部访问

    控制面板-Windows防火墙-高级设置-入站规则 在入站规则窗口中找到“BranchCache内容检索(HTTP-In)”选项并启用此规则. 这时候远程用户通过网站地址即可访问站点程序. 但是如果远 ...

  3. 【leetcode】421. Maximum XOR of Two Numbers in an Array

    题目如下: 解题思路:本题的难点在于O(n)的复杂度.为了减少比较的次数,我们可以采用字典树保存输入数组中所有元素的二进制的字符串.接下来就是找出每个元素的异或的最大值,把需要找最大值的元素转成二进制 ...

  4. 分布式系统理论基础2 :CAP

    本文转自:https://www.cnblogs.com/bangerlee/p/5328888.html 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...

  5. css 导航菜单+下拉菜单

    一.导航菜单 1.横向导航 代码如下: <!doctype html> <html> <head> <meta charset="utf-8&quo ...

  6. inline-block 导致元素下沉 解决方法添加vertical-align:middle属性

    <div class="layui-input-block"> <input name="username" lay-verify=" ...

  7. border-color:transparent;

    http://www.zhangxinxu.com/study/201111/triangle-css-border.html

  8. shell 从函数文件中调用函数的方法

    你可以把所有的函数存储在一个函数文件中 你可以把所有的文件函数加载到当前脚本或命令行 加载函数文件中所有函数的方法: source xxx.sh

  9. 爬虫(三)—— BeautifulSoup模块获取元素

    目录 BeautifulSoup 一.BeautifulSoup简介 二.安装模块 三.解析器 四.Beautiful Soup的使用 五.查找元素 1.遍历文档树 2.搜索文档树 Beautiful ...

  10. 使用mybatis进行一对多嵌套查询时出错:输出结果:Country{id=2, name='美国', minister=[null]}

    即Minister类作为Country类的关联属性. 查询的输出结果是:Country{id=2, name='美国', minister=[null]} <!--mapper.xml内容--& ...