最近有一個在頁面中的圖片載入完成後執行某些操作的需求,那麼應該如何判斷頁面中的圖片是否載入完成呢?
圖片載入事件
圖片的載入分為兩種情況:
-
動態載入(JS生成)
-
非動態載入(html生成)
非動態載入
對於非動態載入的圖片,直接使用window.onload
,在網頁中所有內容載入完畢後執行操作即可。
在jquery
中還有一個$(document).ready()
方法,簡要介紹一下二者的區別。
事件屬性 | window.onload | $(document).ready() |
---|---|---|
執行時機 | 必須等待網頁中所有的內容載入完畢後(包括圖片) | 網頁中所有DOM結構繪製完畢後就執行,可能DOM元素關聯的東西並沒有載入完 |
編寫個數 | 不能同時編寫多個,後面繫結的事件會覆蓋前面的 | 能同時編寫多個 |
簡化寫法 | 無 | $(function() { //... }) |
其他 | 原生方法,jquery中可寫作$(window).load | jquery方法 |
注:IE8及以下不支援onload事件,但支援onreadystatechange
事件,有相容性需要的可以使用該方法,這裡就不展開了。
動態載入
對於動態載入的圖片,可以使用img
標籤的onload
事件,原生實現如下:
var img = new Image()
img.onload = function() {
//...
}
img.src = 'xxx.jpg'
複製程式碼
這裡注意圖片的src
要寫在onload
事件之後,如果先賦值src
,瀏覽器會去非同步載入src
中的值,這個非同步過程可能在onload
之前就完成了,例如圖片快取、js阻塞、圖片很小等等原因,那麼onload
事件將不會執行。將src
寫在onload
之後,可以保證非同步過程在onload
賦值完成後才開始進行,保證能夠正確監聽到onload
事件。
jquery
實現:
$('<img/>').on('load', function() {
$(this).remove();
//...
}).attr('src', 'xxx.jpg');
複製程式碼
在onload
事件中使用$(this)
來對生成的img
進行操作。
ES6
實現:
new Promise((resolve, reject) => {
let img = new Image()
img.onload = function(){
resolve(img)
}
img.src = 'xxx.jpg'
}).then((img) => {
//...
})
複製程式碼
多張圖片ES6
實現:
let images = [
'xxx1.jpg',
'xxx2.jpg',
'xxx3.jpg'
];
let promises = [],
img = [],
imgCount = images.length;
for(let i = 0 ; i < imgCount ; i++){
promises[i] = new Promise((resolve, reject)=>{
img[i] = new Image()
img[i].onload = function(){
resolve(img[i])
}
img[i].src = images[i]
})
}
Promise.all(promises).then((img)=>{
//...
})
複製程式碼
利用Promise.all
在所有圖片都載入完成時執行相應操作。
連結失效
一個站點可能會有很多圖片,假如某個圖片連結失效了,那麼上面程式碼中的Promise.all
也就無法成功執行,如何避免這種情況呢?
可以利用onerror
事件來設定連結失效時執行的操作,例如隱藏圖片或者重新設定一個圖片:
$('img').on('error', function() {
//設定提示錯誤的圖片
$(this).attr('src', 'error.jpg')
})
複製程式碼
假如這個新設定的圖片連結也失效了,那麼瀏覽器將會對同一個錯誤連結一直髮送請求,陷入死迴圈,可以改用one
來繫結error
事件,這樣error
事件對於該img
元素只會執行一次,不會陷入死迴圈。
原文地址: