
前言日常开发表单经常会遇到图片上传需求。要求选择图片上传后端、页面实时渲染缩略图、鼠标悬浮显示删除 / 预览按钮、点击放大预览、删除图片。本篇使用 jQuery FormData 实现代码通俗易懂适合前端新手。要点上传文件必须用FormDataAJAX 需要关闭processData、contentType。实现效果input file 选择图片自动上传接口上传成功页面渲染图片缩略图鼠标悬浮图片淡出预览、删除图标点击预览弹窗放大图片点击删除删掉对应图片更新视图点击遮罩空白处关闭预览弹窗HTML CSS 完整结构!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title图片上传预览删除/title script srchttps://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js/script style /* 多图上传外层 */ .more_pic_box { width: 50%; display: flex; flex-direction: column; } /* 图片容器 */ .img_box { width: 100%; height: 100px; border: 1px solid gray; display: flex; justify-content: start; align-items: center; gap: 10px; } .img_item { width: 80px; height: 80px; position: relative; } .img_item .img_content { width: 100%; height: 100%; } /* hover显示遮罩 */ .img_item:hover .img_delete_show_box { opacity: 1; } .img_delete_show_box { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; position: absolute; right: 0; top: 0; z-index: 99; opacity: 0; transition: all 0.5s; background-color: rgba(0, 0, 0, 0.5); gap: 10px; } .img_delete,.img_show { width: 25px; height: 25px; cursor: pointer; } /* 预览弹窗 */ .preview_modal { display: none; position: fixed; z-index: 999; top: 0; left: 0; width: 100%; height: 100%; justify-content: center; align-items: center; background-color: rgba(0, 0, 0, 0.3); } .previewImage { width: 30%; } /style /head body !--图片预览弹窗-- div classpreview_modal onclickpreviewCancel() img classpreviewImage idpreviewImage altPreview Image /div brbr div classmore_pic_box input typefile classfile_up idfile_four div classimg_box idimgContainer/div /div /bodyJS 核心代码script //后端上传接口地址 let url http://yikatong.kuxia.top //保存后端返回图片地址数组 let pics_url_arr [] $(document).ready(function () { //页面初始化清空file输入框 $(#file_four).val() }) //监听文件选择变化 $(#file_four).change(function () { pics_upload(this) }) /** * 图片上传函数 * param {DOM} el file dom元素 */ function pics_upload(el) { //没有选中文件直接返回 if ($(el)[0].files.length 0) { alert(请选择文件) return } //拿到选中文件对象 let file_data $(el)[0].files[0] //实例化FormData专门用来传文件 let pic_data new FormData() pic_data.append(file, file_data) $.ajax({ url: url /pc/common/upload, type: POST, data: pic_data, dataType: json, cache: false, processData: false, //文件上传必须关闭不要处理data为字符串 contentType: false, //不要自动设置请求头 success: function (res) { if (res.code 1) { //上传成功把图片地址存入数组 pics_url_arr.push(res.data.fullurl) //渲染图片列表 render_pics(pics_url_arr) } else { console.log(res.msg) } }, error: function () { alert(上传失败) } }) } /** * 渲染图片缩略图 * param {Array} data 图片url数组 */ function render_pics(data) { let str $(#imgContainer).empty() if (data data.length 0) { //倒序循环最新上传图片显示在最左边 for (let i data.length - 1; i 0; i--) { str div classimg_item div classimg_delete_show_box img classimg_show onclickimg_show(${data[i]}) alt img classimg_delete onclickdelete_pic(${i}) alt /div img classimg_content src${data[i]} alt /div } $(#imgContainer).html(str) } } /** * 删除图片 * param {Number} index 数组下标 */ function delete_pic(index) { //根据下标删除数组一项 pics_url_arr.splice(index, 1) render_pics(pics_url_arr) $(#file_four).val() } //图片预览弹窗打开 function img_show(img_url) { $(#previewImage).attr(src, img_url) $(.preview_modal).css(display, flex) } //点击遮罩关闭预览只有点背景才关闭点图片不关闭 function previewCancel() { if (event.target.className preview_modal) { $(.preview_modal).css(display, none) } } /script核心逻辑大白话讲解1、FormData 上传文件关键点上传图片不能直接传对象必须用FormData。 AJAX 两个配置不能忘processData:false不让 jQuery 把数据转成查询字符串contentType:false不让 jQuery 自动设置请求头浏览器会自动带上 multipart/form‑datalet pic_data new FormData() pic_data.append(file, file_data) //file就是后端接口接收文件的字段名后端要和这个名字对应2、存储图片地址数组pics_url_arr后端上传成功返回图片完整 urlpush 进数组。整个页面图片全部维护在这个数组。新增图片push删除图片splice(下标,1)删掉数组对应项每次改动数组后调用render_pics()重新渲染页面视图和数组保持同步。这种思路叫数据驱动视图不去操作 DOM 增删修改数组再重新渲染 HTML。3、倒序渲染for (let i data.length - 1; i 0; i--)从数组最后向前循环最新上传的图片显示在最左侧符合用户习惯。4、hover 悬浮遮罩效果.img_item:hover .img_delete_show_box鼠标悬浮外层内部遮罩透明度从 0 变成 1加transition实现淡入动画。5、图片预览弹窗弹窗默认隐藏点击预览图标赋值图片 src设置display:flex显示弹窗。重点previewCancel()做判断只有点击外层遮罩背景才关闭弹窗点击图片本身不会关闭。踩坑记录文件上传 AJAX 不写processData:false、contentType:false后端接收不到文件。input file 选择同一个文件不会触发 change 事件。因为 value 没有变化。删除图片后最好重置file input$(#file_four).val()。后端返回图片路径一定是完整地址否则图片无法显示。onclick 传图片 url如果路径包含特殊字符容易报错实际项目可以做转义处理。总结整体流程input 选择图片触发 change 事件获取 file 对象FormData 封装ajax 上传后端上传成功保存 url 到数组根据数组渲染页面缩略图删除操作修改数组重新渲染视图预览弹窗实现大图查看