今天看到一個(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測(cè)試的覆蓋面不全,所以我上面的結(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 編輯過