有极速快乐十分吗|极速快乐十分走势图|

圖片的預加載的一些潛在問題

你真的了解圖片的預加載嗎?
服務器君一共花費了118.926 ms進行了5次數據庫查詢,努力地為您提供了這個頁面。
試試閱讀模式?希望聽取您的建議

今天看到了一章關于圖片預加載的博文,其代碼如下:

function loadImage(url, callback) 
{     
    var img = new Image(); //創建一個Image對象,實現圖片的預下載     
    img.src = url;     
        
    if (img.complete) 
	{ // 如果圖片已經存在于瀏覽器緩存,直接調用回調函數     
        callback(img);     
        return; // 直接返回,不用再處理onload事件     
    }     
 	img.onload = function () { //圖片下載完畢時異步調用callback函數。         
     	callback(img);     
  	};  
};     

在網上搜索了一下相關文章,大體上都是這個思路。

這個方法功能是ok的,但是有一些隱患。

1. 創建了一個臨時匿名函數來作為圖片的onload事件處理函數,形成了閉包。

相信大家都看到過ie下的內存泄漏模式的文章,其中有一個模式就是循環引用,而閉包就有保存外部運行環境的能力(依賴于作用域鏈的實現),所以img.onload這個函數內部又保存了對img的引用,這樣就形成了循環引用,導致內存泄漏。(這種模式的內存泄漏只存在低版本的ie6中,打過補丁的ie6以及高版本的ie都解決了循環引用導致的內存泄漏問題)。

2. 只考慮了靜態圖片的加載,忽略了gif等動態圖片,這些動態圖片可能會多次觸發onload。

要解決上面兩個問題很簡單,其實很簡單,代碼如下:

img.onload = function () { //圖片下載完畢時異步調用callback函數。         
    img.onload = null;    
    callback(img);     
};  

這樣既能解決內存泄漏的問題,又能避免動態圖片的事件多次觸發問題。

在一些相關博文中,也有人注意到了要把img.onload 設置為null,只不過時機不對,大部分文章都是在callback運行以后,才將img.onload設置為null,這樣雖然能解決循環引用的問題,但是對于動態圖片來說,如果callback運行比較耗時的話,還是有多次觸發的隱患的。隱患經過上面的修改后,就消除了,但是這個代碼還有優化的余地:

if (img.complete) { // 如果圖片已經存在于瀏覽器緩存,直接調用回調函數     
      callback(img);     
      return; // 直接返回,不用再處理onload事件     
}    

關于這段代碼,看相關博文里的敘述,原因如下:

經過對多個瀏覽器版本的測試,發現ie、opera下,當圖片加載過一次以后,如果再有對該圖片的請求時,由于瀏覽器已經緩存住這張圖片了,不會再發起一次新的請求,而是直接從緩存中加載過來。對于 firefox和safari,它們試圖使這兩種加載方式對用戶透明,同樣會引起圖片的onload事件,而ie和opera則忽略了這種同一性,不會引起圖片的onload事件,因此上邊的代碼在它們里邊不能得以實現效果。

確實,在ie,opera下,對于緩存圖片的初始狀態,與firefox和safari,chrome下是不一樣的(有興趣的話,可以在不同瀏覽器下,測試一下在給img的src賦值緩存圖片的url之前,img的狀態),但是對onload事件的觸發,卻是一致的,不管是什么瀏覽器。產生這個問題的根本原因在于,img的src賦值與 onload事件的綁定,順序不對(在ie和opera下,先賦值src,再賦值onload,因為是緩存圖片,就錯過了onload事件的觸發)。應該先綁定onload事件,然后再給src賦值,代碼如下:

function loadImage(url, callback) {     
    var img = new Image(); //創建一個Image對象,實現圖片的預下載     
    img.onload = function(){
        img.onload = null;
        callback(img);
    }
    img.src = url; 
}

這樣內存泄漏,動態圖片的加載問題都得到了解決,而且也以統一的方式,實現了callback的調用。

本文地址:http://www.bavugt.tw/librarys/veda/detail/1338,歡迎訪問原出處。

不打個分嗎?

轉載隨意,但請帶上本文地址:

http://www.bavugt.tw/librarys/veda/detail/1338

如果你認為這篇文章值得更多人閱讀,歡迎使用下面的分享功能。
小提示:您可以按快捷鍵 Ctrl + D,或點此 加入收藏

大家都在看

閱讀一百本計算機著作吧,少年

很多人覺得自己技術進步很慢,學習效率低,我覺得一個重要原因是看的書少了。多少是多呢?起碼得看3、4、5、6米吧。給個具體的數量,那就100本書吧。很多人知識結構不好而且不系統,因為在特定領域有一個足夠量的知識量+足夠良好的知識結構,系統化以后就足以應對大量未曾遇到過的問題。

奉勸自學者:構建特定領域的知識結構體系的路徑中再也沒有比學習該專業的專業課程更好的了。如果我的知識結構體系足以囊括面試官的大部分甚至吞并他的知識結構體系的話,讀到他言語中的一個詞我們就已經知道他要表達什么,我們可以讓他坐“上位”畢竟他是面試官,但是在知識結構體系以及心理上我們就居高臨下。

所以,閱讀一百本計算機著作吧,少年!

《C程序設計語言(第2版新版)》 克尼漢 (作者), 等 (作者, 譯者), 徐寶文 (譯者)

《C程序設計語言》(第2版新版)是由C語言的設計者Brian W.Kernighan和Dennis M.Ritchie編寫的一部介紹標準C語言及其程序設計方法的權威性經典著作。全面、系統地講述了C語言的各個特性及程序設計的基本方法,包括基本概念,類型和表達式、控制流、函數與程序結構、指針與數組、結構、輸入與輸出、UNIX系統接口、標準庫等內容。

更多計算機寶庫...

有极速快乐十分吗
博牛宝沪深策略 中国足球主教练 今日股市最新消息上证指数上证指数2020年预测 她理财攒钱助手怎么样 信投配资 陕西快乐10分走势图 宜昌麻将血流换三张下载 福州麻将单机版下载 云南快乐十分基本走 众诚速配