1. 程式人生 > >關於img的onload事件相容ie下的bug問題

關於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還是暫時保留。