企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
使用layui的多图上传时发现,图片上传到后台,提交表单后,图片顺序与选择的顺序不一致并出现图片重复上传 后发现layui是将多图在前台转为队列,一张张向后台传输,后台处理数据后再回传到前台。但是传输和回填数据是异步进行的,导致回填数据的顺序可能与前台添加数据顺序不一致。控制台中打印choose与done的index结果如下图:![](https://img.kancloud.cn/11/0f/110fa6f7fd80e663bf80574fe6ed6e2a_258x236.png)可以看到choose与done的index不一致。 下面是**错误**示范 html: ~~~html <div class="layui-form-item fl mr20 mb20"> <button type="button" class="layui-btn" id="test2">图片上传</button> <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;"> 预览图: <div class="imglist mt10" id="demo2"></div> </blockquote> </div> ~~~ js: ~~~javascript //多图片上传 upload.render({ elem: '#test2' ,url: "{:url('/api/Upload/upload_img')}" ,accept: 'images' ,size: 5120 ,multiple: true ,number: 9 ,choose: function(obj){ //预读本地文件示例,不支持ie8 var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列 obj.preview(function(index, file, result){ var str = '<div class="layui-inline">'+ '<div class="handle"><i class="layui-icon layui-icon-delete fr del-img"></i></div>' + '<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img">'+ '</div>' $('#demo2').append(str) }); } ,done: function(res,index){ //上传完毕 delete this.files[index]//移除队列中文件 ---这很重要防止之前的图片重复上传 if(res.code==0){ var images = $('input[name=images]').val(); if(images==''){ images = res.data.src; }else{ images += ','; images += res.data.src; } $('input[name=images]').val(images) }else{ layer.msg(res.msg); } } }); //移除图片 $(document).on("click",".del-img",function(e){ var index = $(this).parent().parent().index(); var images = $('input[name=images]').val(); if(images==''){ images_new = ''; }else{ var strs=images.split(","); strs.splice(index,1); images_new = strs.join(","); } $("#demo2").find(".layui-inline")[index].remove(); $('input[name=images]').val(images_new) }); ~~~ 上面的思路是在done中每次将回填数据依次拼接到input中,提交时将input值传到后台,这就导致前台看起来顺序正确,实际顺序却是错的 于是改变思路,既然选择图片预览时的顺序是正确的,并且choose及done的index是相同的,那么可以将后台回传的图片地址以元素节点属性值的方式写入到预览图片中。表单提交的时候获取图片元素列表再将元素列表中对应的属性值拼接为图片列表值即可。 新方案如下: ~~~javascript //多图片上传 upload.render({ elem: '#test2' ,url: "{:url('/api/Upload/upload_img')}" ,accept: 'images' ,size: 5120 ,multiple: true ,number:9 ,choose: function(obj){ var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列 //读取本地文件 obj.preview(function(index, file, result){ console.log('choose'+index) var tr = $(['<div class="layui-inline" >'+ '<div class="handle"><i class="layui-icon layui-icon-delete fr del-img" id="del-'+index+'" data-src=""></i></div>' + '<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img">'+ '</div>'].join('')); $('#demo2').append(tr) }); } ,done: function(res,index){ delete this.files[index]//移除队列中文件 ---这很重要防止之前的图片重复上传 console.log('done'+index) //上传完毕 if(res.code==0){ $('#del-'+index).attr('data-src',res.data.src) if($('.layui-upload-img').length>8){ $('#test2').addClass("layui-btn-disabled"); $('#test2').attr("disabled",true); } }else{ layer.msg(res.msg); } } }); ~~~ 表单提交时获取图片 ~~~javascript //图片提取并限制数量 var images_ids = $('.del-img'); if(images_ids.length>9){ layer.msg("图片最多选择9张"); return false; } if(images_ids.length){ var images = ''; $.each(images_ids,function (index, val) { if(images == ''){ images +=$(val).attr('data-src') }else{ images += ','+$(val).attr('data-src') } }); $(data.form).append('<input name="images" type="hidden" value="'+images+'">');//插入表单 } ~~~ ***!!!特别注意!!!多图上传在done中必须清除队列中上传完成的图片,否则文件将会被重复上传*** ![](https://img.kancloud.cn/28/9b/289bbd21e16719e4ea37f8d3849f06f4_1003x730.png)