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