最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于圖片的預(yù)加載過程中隱藏未知的

 更新時間:2012年12月19日 16:27:36   作者:  
相信大家都看到過ie下的內(nèi)存泄漏模式的文章,其中有一個模式就是循環(huán)引用,而閉包就有保存外部運行環(huán)境的能力(依賴于作用域鏈的實現(xiàn)),所以img.onload這個函數(shù)內(nèi)部又保存了對img的引用,這樣就形成了循環(huán)引用,導(dǎo)致內(nèi)存泄漏
看完了曼聯(lián)與曼城的同城德比,還有漫長的兩個小時,才能看到期待中的國家德比。無聊的很,左右無事,便來論壇閑逛。看到了一章關(guān)于圖片預(yù)加載的博文,其代碼如下:
復(fù)制代碼 代碼如下:

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

在網(wǎng)上搜索了一下相關(guān)文章,大體上都是這個思路。
這個方法功能是ok的,但是有一些隱患。
1 創(chuàng)建了一個臨時匿名函數(shù)來作為圖片的onload事件處理函數(shù),形成了閉包。
相信大家都看到過ie下的內(nèi)存泄漏模式的文章,其中有一個模式就是循環(huán)引用,而閉包就有保存外部運行環(huán)境的能力(依賴于作用域鏈的實現(xiàn)),所以img.onload這個函數(shù)內(nèi)部又保存了對img的引用,這樣就形成了循環(huán)引用,導(dǎo)致內(nèi)存泄漏。(這種模式的內(nèi)存泄漏只存在低版本的ie6中,打過補丁的ie6以及高版本的ie都解決了循環(huán)引用導(dǎo)致的內(nèi)存泄漏問題)。

2 只考慮了靜態(tài)圖片的加載,忽略了gif等動態(tài)圖片,這些動態(tài)圖片可能會多次觸發(fā)onload。
要解決上面兩個問題很簡單,其實很簡單,代碼如下:
復(fù)制代碼 代碼如下:

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

這樣既能解決內(nèi)存泄漏的問題,又能避免動態(tài)圖片的事件多次觸發(fā)問題。
在一些相關(guān)博文中,也有人注意到了要把img.onload 設(shè)置為null,只不過時機不對,大部分文章都是在callback運行以后,才將img.onload設(shè)置為null,這樣雖然能解決循環(huán)引用的問題,但是對于動態(tài)圖片來說,如果callback運行比較耗時的話,還是有多次觸發(fā)的隱患的。
隱患經(jīng)過上面的修改后,就消除了,但是這個代碼還有優(yōu)化的余地:
復(fù)制代碼 代碼如下:

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

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

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

function loadImage(url, callback) {
var img = new Image(); //創(chuàng)建一個Image對象,實現(xiàn)圖片的預(yù)下載
img.onload = function(){
img.onload = null;
callback(img);
}
img.src = url;
}
這樣內(nèi)存泄漏,動態(tài)圖片的加載問題都得到了解決,而且也以統(tǒng)一的方式,實現(xiàn)了callback的調(diào)用。

相關(guān)文章

最新評論

方正县| 筠连县| 静宁县| 禄劝| 罗源县| 大渡口区| 都匀市| 涞源县| 格尔木市| 金阳县| 新蔡县| 奉贤区| 曲松县| 微山县| 河北区| 台前县| 勐海县| 鄂尔多斯市| 西平县| 白玉县| 汕头市| 营山县| 康平县| 宜黄县| 沅陵县| 区。| 黑龙江省| 贵德县| 伊宁县| 兴隆县| 静海县| 盐亭县| 德庆县| 长岭县| 齐河县| 上犹县| 西乡县| 邮箱| 景德镇市| 新津县| 保康县|