JS动态加载图片,无法获取图片宽高的问题

写一个动态加载图片的瀑布流,并用animate实现简单的动画效果,所发现的问题。

首先先贴代码:

//模拟动态数据
var dataInt = {"data":[{"src":"31.jpg"}, {"src":"32.jpg"}, {"src":"33.jpg"}, {"src":"34.jpg"}, {"src":"35.jpg"}, {"src":"36.jpg"}, {"src":"37.jpg"}]};
//滚动事件,重复动态加载数组
$(window).on("scroll", function(){
    //定义一个新的数组
    var newBoxs = [];
    //当符合加载图片条件时
    if (checkScrollSlide()) {
        $.each(dataInt.data, function(index, value){
            var newBox = $("
").addClass("box").appendTo($("#main"));     var newPic = $("
").addClass("pic").appendTo(newBox);     var newImg = $("").attr("src", "img/" + $(value).attr("src")).appendTo(newPic);      newBoxs.push(newBox);     })     //图片初始位置     startPosition($(newBoxs));     //图片结束位置,返回新的colH     //colH为瀑布流每列class为box的div的top值数组(瀑布流以此来定位的)     colH = addMove($(newBoxs), oBoxW, colH); } })
看似很正常,IE和FireFox也能正常显示。但是神奇的Chrome偏偏不领情:

JS动态加载图片,无法获取图片宽高的问题_第1张图片

数一数,定位有毛病的图片7张,和定义的模拟数据恰恰是动态生成一次的数据。

在存入数组前,打印下图片高度,

//获得包括padding、border在内的高度
console.log(newImg.outerHeight());

JS动态加载图片,无法获取图片宽高的问题_第2张图片

可以看到,重复加载了三次图片,第一次加载的图片高度都没能获取到(这里因为是重复加载相同的图片,如果是真实案例,所有图片只要不是重复显示的,高度都是无法获取到的)。

当时这个问题纠结了我很久,

一度认为是Chrome浏览器的问题,

我要去提交BUG.jpg

(哈哈哈哈,现在看来我还是太年轻太天真了)。

实测,FireFox有时也有这个情况(具体不太清楚,还需要多学习浏览器的机制)。


来说说解决方法:

百度了一些资料,才明白这个可能和浏览器缓存渲染的机制有点关系。

可能是图片还没被浏览器所获取到,先把DOM树给加载出来,再来加载图片的原因。

贴下修改后的代码:

//模拟动态数据
var dataInt = {"data":[{"src":"31.jpg"}, {"src":"32.jpg"}, {"src":"33.jpg"}, {"src":"34.jpg"}, {"src":"35.jpg"}, {"src":"36.jpg"}, {"src":"37.jpg"}]};
$(window).on("scroll", function(){
    //定义一个新的数组
    var newBoxs = [];
    //当符合加载图片条件时
    if (checkScrollSlide()) {
        $.each(dataInt.data, function(index, value){
            var newBox = $("
").addClass("box").appendTo($("#main")); var newPic = $("
").addClass("pic").appendTo(newBox); //先加载图片 var img = new Image(); img.src = "img/" + $(value).attr("src"); //当加载成功时 $(img).load(function(){ var newImg = $("").attr({ "src": img.src, "width": img.width + "px", "height": img.height + "px" }); newImg.appendTo(newPic); newBoxs.push(newBox);                 //加载完一组图片后                 if (index == dataInt.data.length - 1) {     //图片初始位置     startPosition($(newBoxs));     //结束位置,返回新的colH     //colH为瀑布流每列class为box的div的top值数组(瀑布流以此来定位的)     colH = addMove($(newBoxs), oBoxW, colH); } }) }) } })

原理很简单,动态加载图片前,先定义一个image对象先让浏览器把要加载的图片缓存好。

再用这个对象load事件,再进行添加DOM。

此时再打印下图片高度:

JS动态加载图片,无法获取图片宽高的问题_第3张图片

再看看效果:

JS动态加载图片,无法获取图片宽高的问题_第4张图片

哈哈哈,完美!!!

不过,感觉流程太复杂了,事件-循环-事件-函数。

目前能力有限,只能这样啦!

ps:刚入职的前端小白,也是第一次写博客。如果有幸被大佬看到,望轻喷!(*╹▽╹*)~

你可能感兴趣的:(JavaScript)