获取图片的offsetHeight时图片还没有加载完怎么办?

新手上路,请多包涵

场景是一个瀑布流的容器,每个图片item的高度由里面的内容和图片撑开,不定高。
我需要高度来决定下一个图片放在瀑布流的哪一个列上,所以我通过offsetHeight来获取每个item的高度。
我对图片进行了预加载(new Image() 随后Image.onload会返回一个Promise),所有返回的Promise放到一个数组里,通过Promise.all进行触发,在Promise.all.then中我打印了item.offsetHeight
同时上面的所有操作都放在了nextTick里
最后的结果是,offsetHeight不总能获得正确的结果,很多次都是部分的高度,比如item最终的高度是435,但此时获得的只是280.我设置了一个50ms的定时器,此时打印的offsetHeight已经可以正常获得了,所以我在nextTick中得到的高度是正在渲染的部分图片的高度
但我明明有了图片的预加载+nextTick,为什么他们没有在图片完全渲染完执行呢?
求助各位大佬,想了一下午+晚上了,没有解决,我该怎么办呢?总不能设置一个几十ms的定时器吧?我现在只有10张图片,后面50 100,可怎么办呀o(╥﹏╥)o

回复
阅读 1.1k
3 个回答

图片是后端返回的,可以让后端顺便返回图片的尺寸,这个不难做到

offsetHeight 获取的应该是 dom 的高度,这里获取图片实际宽高,如果你对图片宽度进行了统一设置再换算一遍最为稳妥

img.onload = function () {
  const result = {
    width: img.naturalWidth,
    height: img.naturalHeight
  }
  img = null
  resolve(result)
}
const arr = [
        "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.daimg.com%2Fuploads%2Fallimg%2F210114%2F1-210114151951.jpg&refer=http%3A%2F%2Fimg.daimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1674612976&t=24323291c98b0f0bb4ae507c7267320a",
        "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Flmg.jj20.com%2Fup%2Fallimg%2F1114%2F040221103339%2F210402103339-8-1200.jpg&refer=http%3A%2F%2Flmg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1674612976&t=be680709e4854da46fbf34506c17fe28",
        "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F14297516724%2F641&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1674612976&t=718101fc71bd540025f94a9c9f286a85",
    ];
    function imgLoad(src) {
        return new Promise((res) => {
            const image = new Image();
            image.src = src;
            document.body.appendChild(image);
            image.onload = function () {
                res(image.offsetHeight);
            };
        });
    }
    Promise.all(arr.map((item) => imgLoad(item))).then((res) => {
        console.log(res);
    });

我试了下是可以的,当然最好还是由后端返回

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏