關於img的onload事件相容ie下的bug問題
我們都知道onload事件是在img載入完成後觸發的事件,但是ie下這個onload事件並沒有想像中的靈,特別是在ie7/ie6下,網上的解釋是ie因為快取關係造成的事件沒有被激發,因為ie這個東西喜歡非同步,所以由快取的問題,網頁獲取到圖片的時間極短(應該比程式碼解釋的時間快)所以造成了onload事件被錯過了。網上一般的說法是把onload事件寫在src賦值之前可以解決這個onload事件不被觸發的問題,但是,實際上如果對於多圖片來說,這個方法其實不太靈。即把下面程式碼:
var image = new Image(); image.src = "xxx.jpg"; image.onload = function() { document.getElementById("img").src = image.src; }
改成
var image = new Image(); image.onload = function() { document.getElementById("img").src = image.src; } image.src = "xxx.jpg";
實際證明,這樣子改可以改善部分情況,但是不是萬試萬靈的。特別是在做多圖片非同步載入時,這個onload事件不被觸發的可能性太高了。於是在網上又看了一堆資料,發現image有一個叫屬性,這個屬性表示圖片是否已經載入完成了,如果載入完成為true,未完成為false,有了這個屬性就可以寫一個定時檢查方法,從而堵上ie的這個bug。以下是我寫的一段程式碼:
obj.find(".proBox > .image > a > img").each(function() { //遍歷圖片,檢查是否需要載入圖片 if ($(this).attr("status") == "unload" || $(this).attr("status") == "") { //未載入的圖片 var realSrc = $(this).attr("real"); var target = this; //建立一個可以給image.onload函式呼叫的物件 var image = new Image(); image.onload = function () { //載入完成 $(target).attr("status", "loaded"); //載入完成 } function check() { //ie7下顯示bug的修復 if (image.) { complete(); } else { setTimeout(function() { check(); }, 500); //每隔0.5秒檢查一次 } } if (document.all) { check(); } image.src = realSrc; $(target).attr("status", "loading"); //載入中 } });
為了讓圖片的真實路徑在網頁載入完成後再非同步載入,所以有很多圖片都要用到onload事件,但是在不加check()方法前,ie7下總是有幾個圖片沒辦法顯示出來,但是加上我現在寫的check方法。網頁顯示正常了。
不過,我突然間由ie的js這麼喜歡非同步的問題想到,其實不用img.complete屬性也是可以在ie下正常觸發事件的,就利用ie最喜歡的非同步方式,我只要推後解決onload事件就可以了,即把image.src=”xxx.jpg”用setTimoute推遲0.1-0.5秒就可以了,這樣子ie就可以先解釋到onload事件,再去請求圖片了,就不怕因為快取問題造成圖片顯示不全了,於是程式碼修改如下:
dobj.find(".proBox > .image > a > img").each(function() { //遍歷圖片,檢查是否需要載入圖片 if ($(this).attr("status") == "unload" || $(this).attr("status") == "") { //未載入的圖片 var realSrc = $(this).attr("real"); var target = this; //建立一個可以給image.onload函式呼叫的物件 var image = new Image(); image.onload = function complete() { //載入完成 $(target).attr("status", "loaded"); //載入完成 } /*function check(){//ie7下顯示bug的修復 if(image.complete){ complete(); }else{ setTimeout(function(){check();},500);//每隔0.5秒檢查一次 } } if(document.all){check();}*/ setTimeout(function() { image.src = realSrc; }, 300); $(target).attr("status", "loading"); //載入中 } });
本文轉自:http://www.css119.com/archives/1658
實驗證明,我的猜想是正確的。不過,原來的complete還是暫時保留。