[1. 问题]
[1.1 问题描述]
[1.2 代码]
[2. 第一个问题的解决]
[2.1 一开始的解决:]
[2.2 最没有错误的解决办法]
- [2.2.1 解决办法的思路:]
- [2.2.2 实现]
[3. 第二个问题的解决思路过程]
[3.1 初始详细描述]
[3.2 找错步骤一:看源码]
[3.3 步骤二:从浏览器控制台定位错误出现的地方]
[3.4 步骤三:根据正常的流程走一遍]
[3.5 步骤四:新开一个页面,对比,继续寻找错误:]
[3.6 步驟五 打开谷歌浏览器的调试工具,在js设置断点]
[3.7 总结一下到目前的进度]
- [3.7.1 我的进度]
- [3.7.2 问题本质]
[3.8 这个问题的终极解决步骤]
[4. 总结]
1. 问题
1.1. 问题描述
当layer.photo()作用的区域内的图片是动态加载产生的的时候,出现两个问题。
一次性加载一个图片之后,方法不生效;第二次加载图片,方法方才生效;且常出现最后一张图片点击之后一直转圈,加载不出来的情况。
点击图片显示图片总共多少张,即i/n中n显示异常。继上一个问题,点击放大查看第一张图片图片,显示1/1张,再点击第二张图片,显示2/2;在加载正常的情况下,若直接点击最后一张图片,则显示2/2张。
1.2. 代码
HTML代码
选择图片
预览图:
图片上传的js代码
upload.render({
elem: '#uploadpics',
url: '/upload/',
multiple: true,
size: 1000 //限制文件大小,单位 KB
,
number: 9,
before: function(obj) {
$('#blockquote_pics').show();
//预读本地文件示例,不支持ie8
obj.preview(function(index, file, result) {
$('#pics').append('')
});
}
});
这里定义了一个方法,写在fun.js里。就是封装了的layer.photos()
function layerphotos() {
console.log("layer.photos() start.");
layer.photos({
photos: '#pics',
anim: 5 //0-6的选择,指定弹出图片动画类型,默认随机(请注意,3.0之前的版本用shift参数)
});
};
2. 第一个问题的解决
2.1. 一开始的解决:
把图片预览显示的代码放在动态生成代码的一起,紧跟着动态生成图片的代码。
obj.preview(function(index, file, result) {
$('#pics').append('')
layerphotos();
}
这个问题,一开始的想法是:在页面加载完成之后执行layerphotos();方法,但根据控制台调试输出的结果发现,页面加载完成的时候方法起作用的div里没有图片,后续加载图片也不会起作用的。
这个值得注意,用控制台输出console.log()的方法判断js代码的执行顺序。
但是,这个问题解决了的原因,还是没有想明白。
目前这个解决方案的不合理之处在于:我如果在图片都加载完成之后,即在preview()函数执行完之后使用photos函数,理论上来说其效果一致,实则不然。考虑这个方法可能是非同步执行。
2.2. 最没有错误的解决办法
2.2.0.1. 解决办法的思路:
layerphotos();方法调用放在图片都加载到页面完成之后,而不是在每一张图片加载之后。
放在每一张图片加载之后并不合理,我们需要在图片全部加载之后才调用layerphotos();去渲染这个div。要使得图片全部加载完成之后再调用这个方法,我们可以在photos()的三个回调函数中解决。
before回调函数里,获取这次加载的图片数量,在循环执行完毕(加载完毕)之后执行layerphotos();方法。
error回调函数里,判断一共有多少张照片,确保加载完毕执行layerphotos();方法。
done回调函数里,执行layerphotos();方法。
这里,三个回调函数,以及before回调函数里执行循环的函数function(index, file, result),其都是非同步执行的。但我们需要达到的效果是,在循环完全执行完毕之后再去执行layerphotos();方法。
2.2.0.2. 实现
修改upload模块源码upload.js,暴露出before回调中获取文件数量的接口
因为我要在before中动态加载上传的图片,所以要在before回调中获取文件数量。然后在我使用浏览器调试工具仔细分析发现,layui2.3.0版本中,upload模块暴露出来的接口只有四个函数:
upload模块before回调暴露出的接口
图片里的fileLength_()是我在源码中找到暴露接口的位置加进去的:
g = {
preview: function(e) {
o.preview(e)
},
upload: function(e, i) {
var t = {};
t[e] = i, o.upload(t)
},
pushFile: function() {
return o.files = o.files || {}, layui.each(o.