简单描述:一次上传N张图片(N可自定义);上传完后图片回显,鼠标放到已经上传的图片上后,显示删除,点击后可以删除图片,鼠标离开后,图片恢复。

效果:一次上传多个图片后的效果

上传成功:

鼠标悬浮到图片上:图片变成垃圾桶图片,点击可以删除该图片,鼠标离开,图片恢复

鼠标离开:图片恢复

代码:

//html代码
<div class="col-md-12">
<label class="control-label flex" style="margin-top: 10px;">
上传附件<span class="star align-items">*</span>
</label>
<form id="imgForm">
<div class="" id="imgDiv">
<img th:src="@{/assets-new/apps/img/shangchuan.png}" id="imgIcon"
width="35px" height="35px"/>
<input type="file" id="seledIcon" style="display:none"
multiple="multiple" accept="image/gif,image/jpg,image/png,image/JPEG"/>
</div></form>
<input type="hidden" name="contractIcon" id="contractIcon"/>
</div> 
//js代码
$("#imgIcon").on("click", function () {
$("#seledIcon").trigger("click");
}); 
//我放在add.html中了
<script type="text/javascript" th:inline="javascript" xmlns:th="http://www.w3.org/1999/xhtml">
<![CDATA[
imgUpload({
inputId:'seledIcon', //input框id
upUrl: rootPath +'/oper/contract/uploadImg', //提交地址
data:'file', //参数名
num:"9"//最多上传图片个数 可自定义
});
]]>
</script>
//js代码
var imgSrc = []; //存放图片路径
var imgFile = []; //存放文件流
var imgName = []; //存放图片名字
//选择图片的操作
function imgUpload(obj) {
var oInput = '#' + obj.inputId;
//用on是因为它可以动态的绑定事件
$(oInput).on("change", function() {
imgFile = [];
//获取type=file的input
var fileImg = $(oInput)[0];
//得到所有的图片列表
var fileList = fileImg.files;
for(var i = 0; i < fileList.length; i++) {
       //springboot内置的tomcat文件传输默认是1M 过滤超过1M的文件 
if(fileList[i].size<1024*1024){
//得到每个图片的路径
var imgSrcI = getObjectURL(fileList[i]);
//向文件名的数组末尾添加此文件名
imgName.push(fileList[i].name);
//向路径的数组末尾添加路径
imgSrc.push(imgSrcI);
//在文件流数组的末尾添加文件
imgFile.push(fileList[i]);
}
} var fd = new FormData($('#imgForm')[0]);
//由于fd对象中已经包含<input type='file'>的input标签,如果不删除,就会造成重复上传
fd.delete("file");
//将文件流循环添加到FormData对象中
for(var i=0;i<imgFile.length;i++){
fd.append(obj.data,imgFile[i]);
}
//已上传的图片个数
var numed = document.getElementsByClassName("imgTofile").length;
     //新添加的文件列表的长度,有几张图
var numing = fileList.length;
//图片总数
     var num = numed + numing;
if (imgName.length<1){
layer.msg("请选择上传的图片!");
return false;
} else if(num >obj.num){
layer.msg("最多只能上传"+obj.num+"张图片!");
return false;
}else{
//上传所有的图片
submitPicture(obj.upUrl, fd);
}
}); } //上传(将文件流数组传到后台)
function submitPicture(url,data) {
  //点击上传后,就清空,解决上传完图片后,再点击上传,不选图片,直接关闭,也能上传的bug
  imgStr.splice(0,imgStr.length);
  imgFile.splice(0,imgFile.length);
  imgName.splice(0,imgName.length);
for (var p of data) {
console.log(p); }
if(url&&data){
$.ajax({
url: url,
type: "post",
data: data,
async: true,
//下面这两个要写成false,要不然上传不了。
processData: false,
contentType: false,
success: function(data) {
var contractIcon = data.substring(1,data.length-1);
var myArray=new Array();
myArray = contractIcon.split(",");
layer.msg("成功上传"+myArray.length+"张图片");
var idSet = [];//存放上传成功图片的id
for(var i=0; i<myArray.length;i++){
var str = "img"+ makeId();
var html = ' <img th:src="" class="imgTofile" id="'+ str +'" value="'+myArray[i]+'" onclick="deleteImg('+ str +')" width="35px" height="35px"/>'
idSet.push(str);
$("#imgDiv").append(html);
}
          //回显图片
for(var j=0;j<myArray.length;j++){
var obj = "#"+idSet[j];
            var imgIcon = rootPath + 'oper/contract/downLoadImage?contractIcon=' + myArray[j];
$(obj).attr('src', imgIcon);
}
          //鼠标悬浮图片,显示'删除'图片,鼠标离开,图片恢复
$(".imgTofile").each(function() {
var imgName = '';
$(this).mouseover(function () {
imgName = $(this).attr('value');
$(this).attr('src',rootPath +'/assets-new/apps/img/shanchu.png');
});
$(this).mouseleave(function () {
$(this).attr('src',rootPath + 'oper/contract/downLoadImage?contractIcon=' + imgName);
});
});
},
error:function(xhr,emsg,e) {
//打印ajax发生的错误
console.log(e);
//答应出ajax请求返回的文本信息
console.log(xhr.responseText());
}
});
}else{
layer.msg('数据格式不正确!');
}
}
//图片预览路径
function getObjectURL(file) {
var url = null;
if(window.createObjectURL != undefined) { // basic
url = window.createObjectURL(file);
} else if(window.URL != undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if(window.webkitURL != undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
}
//删除图片
function deleteImg(str) {
var parent = document.getElementById("imgDiv");
parent.removeChild(str);
}
//获取5为随机字符串做图片id
function makeId()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
//后台java代码

//配置文件constant.properties
#上传图标的存放路径
constant.image_path=D:\\image\\icon
#上传图标的临时存放路径
constant.image_temp_path=D:\\image\\temp //Controller
@Value("${constant.image_path}")
private String imagePath; @Value("${constant.image_temp_path}")
private String imageTempPath; @RequestMapping("/uploadImg")
@ResponseBody
public String uploadImg(MultipartFile file[]) throws Exception {
List<String> list = new ArrayList<>();
for (MultipartFile f : file) {
// 图片的名字用毫秒数+图片原来的名字拼接
String imgName = System.currentTimeMillis() + f.getOriginalFilename();
//上传文件
uploadFileUtil(f.getBytes(), imageTempPath, imgName);
list.add(imgName);
}
String str = StringUtils.join(list,",");
return str;
} private void uploadFileUtil(byte[] file, String imgPath, String imgName) throws Exception {
File targetFile = new File(imgPath);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
FileOutputStream out = new FileOutputStream(imgPath + File.separator + imgName);
out.write(file);
out.flush();
out.close();
} //下载文件
@RequestMapping("/downLoadImage")
public void downLoadImage(String contractIcon, HttpServletResponse response) {
if (!Tools.notEmpty(contractIcon)) {
return;
}
File file = null;
file = new File(imagePath + File.separator + contractIcon);
if (!file.exists()) {
file = new File(imageTempPath+ File.separator + contractIcon);
} if (file.exists()) {
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream(file));
out = new BufferedOutputStream(response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
try {
// 设置response内容的类型
response.setContentType(new MimetypesFileTypeMap().getContentType(file));
// 设置头部信息
response.setHeader("Content-disposition", "attachment;filename=" + contractIcon);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} } 

总结:改完之后成就感还是有那么一点的o(*^@^*)o,分享给大家!!!共同进步。谢谢原博客https://blog.csdn.net/jtshongke/article/details/78516559带来的帮助。

SpringBoot图片上传(五) 上一篇的新版本,样式修改后的的更多相关文章

  1. 使用webuploader实现大文件上传分片上传

    本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...

  2. input文件上传(上传单个文件/多选文件/文件夹、拖拽上传、分片上传)

    //上传单个/多个文件 <input title="点击选择文件" id="h5Input1" multiple="" accept= ...

  3. python 全栈开发,Day86(上传文件,上传头像,CBV,python读写Excel,虚拟环境virtualenv)

    一.上传文件 上传一个图片 使用input type="file",来上传一个文件.注意:form表单必须添加属性enctype="multipart/form-data ...

  4. Webfrom 上传 单个上传 多个上传

    文件上传控件:FileUpload - 控件,界面+方法+属性Button/LinkButton/ImageButton FileUpload控件:1.SaveAs("要上传到服务器的绝对路 ...

  5. 项目总结21:项目总结21:input实现多图上传(FormData)(上传OSS并保存数据库)

    项目总结21:input实现多图上传(FormData)(上传OSS并保存数据库) 备注:本案例,作为Demo,包含少量的项目业务逻辑,input多图上传的逻辑是完整的: 不废话直接上代码 1-前端标 ...

  6. php实现大文件上传分片上传断点续传

    前段时间做视频上传业务,通过网页上传视频到服务器. 视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制:2,请求时间过长, ...

  7. 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件

    [源码下载] 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...

  8. 文件上传~Uploadify上传控件~续(多文件上传)

    对于Uploadify文件上传之前已经讲过一次(文件上传~Uploadify上传控件),只不过没有涉及到多文件的上传,这回主要说一下多个文件的上传,首先,我们要清楚一个概念,多文件上传前端Upload ...

  9. git commit -a -m "DM 1、获取aliOssSTS值,计算签名,实现视频PUT/POST2种上传方式上传;"

    git commit -a -m "DM 1.获取aliOssSTS值,计算签名,实现视频PUT/POST2种上传方式上传:" 微信小程序的视频上传

随机推荐

  1. 【BZOJ5499】[2019省队联测]春节十二响(贪心)

    [BZOJ5499][2019省队联测]春节十二响(贪心) 题面 BZOJ 洛谷 题解 如果是一条折链,显然维护两侧的值,每次两个堆分别弹出一个\(max\)然后合并一下,最后再放回去就可以了. 那么 ...

  2. Shell入门及实践

    解释器 解释器是一种命令解释器,主要作用是对命令进行运行和解释,将需要执行的操作传递给操作系统内核并执行 #!/bin/bash(默认),指定解释器 #!/bin/bash #这是第一个shell脚本 ...

  3. CentOS配置history记录每个用户执行过的命令

    一个偶然的机会,看到了这个文档,先存下来,后续使用的话直接就加进去了 要记录登录者的用户名.IP.操作记录,在/etc/bashrc末尾加入几个环境变量,用于history命令显示用户ip等内容,完成 ...

  4. Meterpreter命令详解

      0x01初识Meterpreter 1.1.什么是Meterpreter Meterpreter是Metasploit框架中的一个扩展模块,作为溢出成功以后的攻击载荷使用,攻击载荷在溢出攻击成功以 ...

  5. 20175221 《Java程序设计》第5周学习总结

    20175221   <Java程序设计>第5周学习总结 教材学习内容总结 接口的定义 接口声明:interface 接口名 接口体中只可以有常量,而没有变量 接口体中只有抽象方法(可省略 ...

  6. DMA设计

    目录 DMA设计 DMA框架 手册请看英文手册 芯片特性 请求来源 协议简述 基本时序 模式 协议 数据大小的描述 具体完整的实例时序 代码设计 驱动程序 测试程序 测试 参考链接 title: DM ...

  7. vue动态添加对象属性,视图不渲染

    发现数据确实改变了.但是视图没有渲染.原因是赋值的问题,应该这样动态增加属性 vm.$set(vm.template.titleAttachInfoDetail,newKey,newVal) vm 当 ...

  8. 快速定位XPATH

    本文主要介绍如何快速定位WEB端的xpath. 浏览器:Chrome.火狐浏览器 两种浏览器的定位方法都是一样:按F12键,可查看开发者工具 上图,开发者工具最左上角是定位按钮,点击此按钮,再点击浏览 ...

  9. HDU 1584(蜘蛛牌 DFS)

    题意是在蜘蛛纸牌的背景下求 10 个数的最小移动距离. 在数组中存储 10 个数字各自的位置,用深搜回溯的方法求解. 代码如下: #include <bits/stdc++.h> usin ...

  10. 关于使用python ~取反操作符带出的一系列问题

    晚上的时候,无意之间看到stackoverflow上面的一个编程挑战赛,各路高手各种搞事,看到python的地方突然发现用了很多位运算的符号,但是~符号引起了我和同事的注意. 我们很少在程序中使用这种 ...