使用的前端技术:vue2.x + antd1.7.8;其中出问题的组件:popupover组件.
问题描述:使用popupover组件的visible参数控制隐藏显示;popupover组件中使用了图片,鼠标移入后,会导致指示箭头偏离源头元素;第2+n次恢复正常
思考:鼠标移入目标元素后,目测图片有明显的加载过程(图片从上到下慢慢加载),此时指示箭头错位.问题原因就很明显了:
1.显示popupover弹窗的时候图片尚未加载,popupover组件内部文字内容高度计算出指示箭头的位置;
2.紧接着开始加载图片,图片加载结束后开始渲染图片,此时会撑高popupover弹窗,遗憾的是,popupover组件并没有监听高度变化这事件,导致弹窗变高,但指示箭头位置并没有跟着变.
处理方案(蛋疼蛋疼蛋疼):
知道了原因,解决就很简单了,在显示弹窗前,提前加载图片就完事.万万没想到这是我调试一下午的开端.
提前加载图片有很多种方式,最粗暴的方式就是在页面写个用样式隐藏的图片.如果图片较少可以用,但图片很多的话,会导致页面加载时间变长.
<img src="/shiba/yituge.png" style="display:none">
身为一个老前端肯定不会用这种方式,那就用js提前加载.
/** 预加载图片* */
export function preloadImg(url){
return new Promise((resolve)=>{
let img = document.createElement("img");
img.onload = () =>{
resolve(img);
}
img.src=url;
});
}
//使用:
await preloadImg('/shiba/yituge.png');
this.控制popupover显示的变量 = true;
分分钟搞定,自信满满的测试.咦,还不好?代码有问题?不应该啊,反复测试修改后,难道是我promise+async+await用的不对?那就改成普通回调的方式逝世.
/** 预加载图片* */
export function preloadImg(url,cb){
// 上面的方法体 let img = document.createElement("img");
img.onload = () =>{
cb && cb(img)
}
img.src=url;}
这应该没问题了吧,然后又自信满满的测试,what a fake,还是老样子,(此时开始有点蛋疼了,蛋疼+1).
难道是浏览器出bug了?重启浏览器,前端疑难杂症终极解决方案,然并卵(蛋疼+10).
又经过一系列的修改测试,换浏览器测试,问题仍然存在.(蛋疼+100)
难道是我电脑有毒?让同事局域网内访问我的开发地址,她竟然没问题!!!(蛋疼+10086)
此时已经距发现问题已经过了2个多小时,我已经开始有点暴躁了.出去抽根烟冷静冷静,回想自己调试过程,突然想到一个细节.鼠标移入目标元素的时候,图片请求了2次
当时没在意,现在想想这是有问题的,明明只用js预加载了一次,但是出现2次请求,难道第二次是图片加载又请求了一次?再结合同事访问并没有出现问题,我顿悟了.丢下烟,回到办公桌看浏览器设置,果然如此.
开启这个配置后,本地开发就不会使用缓存文件.在我碰到的问题中鼠标移入js加载图片一次,显示弹层时候图片渲染渲染又重新加载了一次,就等于我的预加载工作白做了.
但从另一个角度想:没有哪个普通用户会打开浏览器控制台,并且开启这个开关,也就是说我的问题根本就不是问题,我只是自己把自己给坑了-_-.
不暴躁了,蛋也不疼了.继续愉快的代码.
问题复盘:
其实在调试过程中,也特意去观察过请求,看到2次图片请求,也没深入去想,只是感到有点奇怪.
SO:抽烟真的有助于写代码(并不是).