今天看到一個(gè)面試題,是關(guān)于img圖片加載方面的,有必要記錄一下。其實(shí)關(guān)于這個(gè)問題,只要知道圖片什么時(shí)候加載完成就能解決了。
通過onload事件判斷Img標(biāo)簽加載完成
實(shí)現(xiàn)邏輯:新建一個(gè)Image對(duì)象實(shí)例,為實(shí)例對(duì)象設(shè)置src屬性等,在onload事件中添加此實(shí)例對(duì)象到父元素中,然后將圖片地址數(shù)組中的第一個(gè)元素剔除,繼續(xù)調(diào)用此方法直到存儲(chǔ)圖片地址的數(shù)組為空。
代碼
const imgArrs = [...]; // 圖片地址
const content = document.getElementById('content');
const loadImg = () => {
if (!imgArrs.length) return;
const img = new Image(); // 新建一個(gè)Image對(duì)象
img.src = imgArrs[0];
img.setAttribute('class', 'img-item');
img.onload = () => { // 監(jiān)聽onload事件
// setTimeout(() => { // 使用setTimeout可以更清晰的看清實(shí)現(xiàn)效果
content.appendChild(img);
imgArrs.shift();
loadImg();
// }, 1000);
}
img.onerror = () => {
// do something here
}
}
loadImg();
</script>
實(shí)現(xiàn)效果
加上setTimeout
后,看到的效果更加明顯,我這里加了500毫秒的延遲(錄屏軟件只支持錄制8秒的時(shí)間...)
其實(shí)我在網(wǎng)上還看到了一種答案,通過onreadystatechange事件實(shí)現(xiàn)監(jiān)聽,于是在我本地調(diào)試了一下,發(fā)現(xiàn)并不能實(shí)現(xiàn),img實(shí)例對(duì)象上并沒有這個(gè)屬性方法。查了查MDN,發(fā)現(xiàn)目前僅有XmlHttpRequest
對(duì)象和Document
對(duì)象中存在onreadystatechange
屬性,而對(duì)于其它元素onreadystatechange
此屬性并不存在。
「因此對(duì)于其它元素需要慎用onreadystatechange
事件」。
不過我電腦上目前只有Chorme
和Safari
兩種瀏覽器,對(duì)于onreadystatechange
測試的覆蓋面不全,所以我上面的結(jié)論可能還需要進(jìn)一步驗(yàn)證才行,感興趣的掘友可以調(diào)試一下~。
擴(kuò)展知識(shí)
img標(biāo)簽是什么時(shí)候發(fā)送圖片資源請(qǐng)求的?
HTML文檔渲染解析,如果解析到img標(biāo)簽的src時(shí),瀏覽器就會(huì)立刻開啟一個(gè)線程去請(qǐng)求圖片資源。
動(dòng)態(tài)創(chuàng)建img標(biāo)簽,設(shè)置src
屬性時(shí),即使這個(gè)img標(biāo)簽沒有添加到dom元素中,也會(huì)立即發(fā)送一個(gè)請(qǐng)求。
// 例1:
const img = new Image();
img.src = 'http://xxxx.com/x/y/z/ccc.png';
上面的代碼如果運(yùn)行起來后,就會(huì)發(fā)送請(qǐng)求。 如圖:
再看一個(gè)例子:創(chuàng)建了一個(gè)div
元素,然后將存放img標(biāo)簽
元素的變量添加到div
元素內(nèi),而div
元素此時(shí)并不在dom
文檔中,頁面不會(huì)展示該div
元素,那么瀏覽器會(huì)發(fā)送請(qǐng)求嗎?
// 例2:
const img = `<img src='http://xxxx.com/x/y/z/ccc.png'>`;
const dom = document.createElement('div');
dom.innerHTML = img;
答案:會(huì)請(qǐng)求。如圖:
通過設(shè)置css屬性能否做到禁止發(fā)送圖片請(qǐng)求資源?
- 給
img標(biāo)簽
設(shè)置樣式display:none
或者visibility: hidden
,隱藏img標(biāo)簽
,無法做到禁止發(fā)送請(qǐng)求。
<img src="http://xxx.com/x/sdf.png" style="display: none;">
或者
<img src="http://xxx.com/x/sdf.png" style="visibility: hidden;">
- 將圖片設(shè)置為元素的背景圖片,但此元素不存在,可以做到禁止發(fā)送請(qǐng)求。
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title></title>
<style>
.test {
height: 200px;
background-image: url('http://eb118-file.cdn.bcebos.com/upload/39148b2a545b48bf9b4ee95fd1b7f1eb_1515564089.png?');
}
</style>
</head>
<body>
</body>
</html>
dom文檔中不存在test
元素時(shí),即使設(shè)置了背景圖片,也不會(huì)發(fā)送請(qǐng)求,只有test
元素存在時(shí)才會(huì)發(fā)送請(qǐng)求。
另外這個(gè)例子其實(shí)有點(diǎn)不太貼切,img標(biāo)簽
和background-image
二者有著本質(zhì)的區(qū)別。一個(gè)屬于HTML標(biāo)簽,另一個(gè)屬于css樣式,加載機(jī)制和解析順序也不同。
?一個(gè)完整的頁面是由js
、html
、css
組成的,按照解析機(jī)制,html
元素會(huì)優(yōu)先解析,盡管css
樣式是放在head
標(biāo)簽內(nèi)的,但也不意味著它會(huì)優(yōu)先加載,它只有等到html
文檔加載完成后才會(huì)執(zhí)行。而img標(biāo)簽
屬于網(wǎng)頁內(nèi)容,所以img標(biāo)簽
會(huì)隨著網(wǎng)頁解析渲染優(yōu)先于css樣式表
加載出來。
?
文章中若有描述不正確的地方,歡迎掘友們糾正~
閱讀原文:https://mp.weixin.qq.com/s/3K1tksZfiAFTfRzD9Q6ZyA
該文章在 2025/1/13 10:46:29 編輯過