今天看到一个面试题,是关于img图片加载方面的,有必要记录一下。其实关于这个问题,只要知道图片什么时候加载完成就能解决了。

通过onload事件判断Img标签加载完成

实现逻辑:新建一个Image对象实例,为实例对象设置src属性等,在onload事件中添加此实例对象到父元素中,然后将图片地址数组中的第一个元素剔除,继续调用此方法直到存储图片地址的数组为空。

代码

 1const imgArrs = [...]; 
 2const content = document.getElementById('content');
 3const loadImg = () => {
 4  if (!imgArrs.length)  return;
 5  const img = new Image(); 
 6  img.src = imgArrs[0];
 7  img.setAttribute('class', 'img-item');
 8  img.onload = () => { 
 9    
10      content.appendChild(img);
11        imgArrs.shift();
12        loadImg();
13    
14  }
15  img.onerror = () => {
16    
17  }
18}
19  loadImg();
20
21</script>

实现效果

加上setTimeout后,看到的效果更加明显,我这里加了500毫秒的延迟(录屏软件只支持录制8秒的时间…)

其实我在网上还看到了一种答案,通过onreadystatechange事件实现监听,于是在我本地调试了一下,发现并不能实现,img实例对象上并没有这个属性方法。查了查MDN,发现目前仅有XmlHttpRequest对象和Document对象中存在onreadystatechange属性,而对于其它元素onreadystatechange此属性并不存在。

因此对于其它元素需要慎用onreadystatechange事件

不过我电脑上目前只有ChormeSafari两种浏览器,对于onreadystatechange测试的覆盖面不全,所以我上面的结论可能还需要进一步验证才行,感兴趣的掘友可以调试一下~。

扩展知识

img标签是什么时候发送图片资源请求的?

  1. HTML文档渲染解析,如果解析到img标签的src时,浏览器就会立刻开启一个线程去请求图片资源。

  2. 动态创建img标签,设置src属性时,即使这个img标签没有添加到dom元素中,也会立即发送一个请求。

 1
 2const img = new Image();
 3img.src = 'http://xxxx.com/x/y/z/ccc.png';

上面的代码如果运行起来后,就会发送请求。 如图:

再看一个例子:创建了一个div元素,然后将存放img标签元素的变量添加到div元素内,而div元素此时并不在dom文档中,页面不会展示该div元素,那么浏览器会发送请求吗?

 1
 2const img = `<img src='http://xxxx.com/x/y/z/ccc.png'>`;
 3const dom = document.createElement('div');
 4dom.innerHtml = img;

答案:会请求。如图:

通过设置css属性能否做到禁止发送图片请求资源?

  1. img标签设置样式display:none或者visibility: hidden,隐藏img标签,无法做到禁止发送请求。
 1<img src="http://xxx.com/x/sdf.png" style="display: none;">
 2或者
 3<img src="http://xxx.com/x/sdf.png" style="visibility: hidden;">
  1. 将图片设置为元素的背景图片,但此元素不存在,可以做到禁止发送请求。
 1<!DOCTYPE html>
 2<html lang='en'>
 3<head>
 4    <meta charset='UTF-8'>
 5    <title></title>
 6    <style>
 7        .test {
 8            height: 200px;
 9            background-image: url('http://eb118-file.cdn.bcebos.com/upload/39148b2a545b48bf9b4ee95fd1b7f1eb_1515564089.png?');
10        }
11    </style>
12</head>
13<body>
14<div></div>
15</body>
16</html>
17

dom文档中不存在test元素时,即使设置了背景图片,也不会发送请求,只有test元素存在时才会发送请求。

另外这个例子其实有点不太贴切,img标签background-image二者有着本质的区别。一个属于HTML标签,另一个属于css样式,加载机制和解析顺序也不同。

一个完整的页面是由jshtmlcss组成的,按照解析机制,html元素会优先解析,尽管css样式是放在head标签内的,但也不意味着它会优先加载,它只有等到html文档加载完成后才会执行。而img标签属于网页内容,所以img标签会随着网页解析渲染优先于css样式表加载出来。

文章中若有描述不正确的地方,欢迎掘友们纠正~。

参考文章

  1. developer.mozilla.org/en-US/docs/…
  2. blog.csdn.net/m0_52545254…
  3. www.cnblogs.com/lyt0207/p/1…
个人笔记记录 2021 ~ 2025