網頁制作poluoluo文章簡介:之前在做一個圖片浏覽效果時,要看後面的小圖必須等到前面的加載完,而且大圖的位置是在大量的小圖後面,導致大圖要等到小圖都加載完才能顯示,為了解決這個問題,就想到了Lazyload效果。
之前在做一個圖片浏覽效果時,要看後面的小圖必須等到前面的加載完,而且大圖的位置是在大量的小圖後面,導致大圖要等到小圖都加載完才能顯示,為了解決這個問題,就想到了Lazyload效果。
現在很多網站都用了類似的效果,如淘寶、Bing等。
這個圖片延遲加載效果是在Lazyload的基礎上擴展的,主要擴展了獲取img元素,獲取src和圖片加載的部分。
兼容:ie6/7/8, firefox 3.5.5, opera 10.10, safari 4.0.4, chrome 3.0
其中safari和chrome部分功能不支持。
效果預覽
程序說明
【獲取圖片】
先定義filter函數作為篩選程序:
代碼 var getSrc = opt.getSrc,
然後用這個filter函數篩選出需要的圖片集合:
如果要自定義圖片集合可以在程序可選參數的images屬性來設置,否則自動從容器獲取img元素作為圖片集合。
這裡的filter其實是包裝了篩選樣式cls、獲取src的方法getSrc和占位圖holder三個參數的_filter篩選程序。
在_filter程序中,會對圖片集合進行篩選和整理。
如果自定義了"class"篩選樣式,會自動排除樣式不對應的圖片:
再用getSrc獲取原圖地址,即實際要顯示的圖片地址。
如果有自定義getSrc會優先使用。
沒有的話,再通過保存原圖地址的_attribute自定義屬性從元素獲取。
最後才直接從元素的src屬性獲取。
接著排除src不存在的:
要注意處理原圖地址就是元素當前src的情況:
如果complete為true,說明圖片已經載入完成了,可以排除;
如果是chrome或safari,不能取消當前加載,所以也排除掉(具體看圖片的HTTP請求部分)。
否則,用removeAttribute移除src屬性來取消圖片當前的加載。
如果設置了holder占位圖,就重新設置圖片src:
最後把原圖地址記錄到元素的_attribute自定義屬性中:
逐個圖片元素篩選整理後,就得到要加載的圖片集合了。
【圖片加載】
ImagesLazyLoad相比LazyLoad,已經實現了_onLoadData加載程序,不需要再自己定義加載。
在_onLoadData程序中,主要是用來顯示圖片。
先用_hasAttribute方法判斷是否有_attribute自定義屬性。
在_hasAttribute方法中是這樣判斷的:
由於ie6/7跟其他浏覽器對attribute和property的理解不同,所以要分開處理,詳細參考這裡的attribute/property。
為了保證兼容性,程序會優先使用attribute的方式來操作自定義屬性。
當img有_attribute自定義屬性時,就用getAttribute來獲取原圖地址,並設置img的src,在用removeAttribute來移除自定義屬性。
移除的意義在於,當有多個實例使用同一個元素時,能保證圖片加載一次後就不會重復加載,即防止實例間的沖突。
【圖片的HTTP請求】
這裡說說開發過程中發現的一些關於圖片加載的問題。
首先是加載空字符串的問題,如果給img的src設為空字符串的話,可能會得到意料之外的結果。
例如在 http://xxx/test.htm 裡面的 會發生以下情況:
ie 會產生相對地址的請求,即:http://xxx/
Safari/Chrome 會產生當前頁面地址的請求,即:http://xxx/test.htm
Opera/Firefox 不會產生請求
詳細參考Nicholas C. Zakas的“Empty image src can destroy your site”。
如果不想加載圖片,不應該把src設為空值,因為還可能會發出請求,浪費資源。
可以像程序那樣,通過removeAttribute來移除就行了。
還有一個問題是在Safari和Chrome,由於webkit內核的bug,正在加載的圖片並不能取消加載。
所以程序在取消圖片加載的部分,如果是Safari或Chrome會繼續加載,不進行延遲。
這個問題最初從lifesinger的datalazyload的說明部分看到的,具體可以自己用Fiddler來測試。
更多相關資料可以參考lifesinger的“圖片的HTTP請求”。
【繼承結構】
在發布的程序中,這是第一個用了繼承的,本人平時也沒怎麼用到,所以還不成熟,算是試試水吧。
程序用wrapper來做繼承,詳細參考工具庫的說明。
先用wrapper給ImagesLazyLoad包裝(繼承)LazyLoad:
再用extend擴展prototype,添加子類的方法函數:
其中_initialize方法用來設置子類屬性,由於覆蓋了父類的同名方法,所以要通過LazyLoad.prototype._initialize來調用,還要注意用call來修正this。
還有_setOptions方法用來設置子類的可選屬性:
子類的_setOptions方法也覆蓋了父類的方法,解決方法同_initialize。
其中第一個參數是子類的可選屬性,第二個參數是子類定義的屬性,即不再是可選而是由程序來定義的屬性。
總體來說,這是個簡陋的繼承,等以後積累了一定經驗再來擴展吧。
使用技巧
【設置src】
有幾個方法可以設置原圖地址:
1,正常設置src:漸進增強,不支持js時也能顯示,但chrome和safari有bug,不支持這種方式;
2,把原圖地址設置到自定義屬性中:所有浏覽器都兼容,但在不支持js時圖片不能顯示;
3,用自定義函數獲取:使用在比較復雜的情況,需要手動設置。
具體還是要根據實際情況來選擇。
【設置holder】
如果使用了holder占位圖,程序會自動設置圖片元素顯示占位圖。
推薦使用loading圖片來設置,但loading圖往往跟原圖的尺寸是不同的。
如果img設置了原圖寬高,又想保持loading圖的尺寸,把它設為背景就可以了。
但這樣在ie下,不設置src默認會有一個小圖標。
要去掉這個小圖標可以設置holder為一個透明圖片的鏈接,或者參考這裡的TRANSPARENT“做”一個透明圖片。
實例中也是這樣設置的,可以參考一下。
【執行程序】
千萬不能在window.onload中執行,因為那時圖片都已經加載完了。
而應該在容器後面(window的話是文檔結尾)或DOMContentLoaded中執行。
程序源碼
完整實例下載