在頁面很長(超過3屏)且圖片又很多時,預設情況下瀏覽器會載入所有圖片,有可能導致第二屏的圖片顯示出來了,但第一屏的圖片還在載入,這種情況最適合用"javascript延時載入"來改善使用者體驗.
原理:
1.根據圖片元素距頁面頂部的距離,判斷圖片自身在第幾屏
2.所有圖片元素的src值先不設定,改而用其它自訂屬性,比如src寫成lazy_src(這樣瀏覽器就不會主動載入圖片)
3.根據1的判斷,如果輪到自己登場了(即到頂部的距離變化了,比如使用者拉動捲軸了),則將lazy_src值賦值為src,這樣瀏覽器就開始載入了.
代碼:(收集於網上)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>js延時載入</title> <script type="text/javascript"> lazyLoad = (function () { var map_element = {}; var element_obj = []; var download_count = 0; var last_offset = -1; var doc_body; var doc_element; var lazy_load_tag; function initVar(tags) { doc_body = document.body; //判斷是否為IE的"怪異模式" doc_element = document.compatMode == 'BackCompat' ? doc_body : document.documentElement; lazy_load_tag = tags || ["img", "iframe"]; }; function initElementMap() { //var all_element = []; //從所有相關元素中找出需要延時載入的元素 for (var i = 0, len = lazy_load_tag.length; i < len; i++) { var el = document.getElementsByTagName(lazy_load_tag[i]); for (var j = 0, len2 = el.length; j < len2; j++) { if (typeof (el[j]) == "object" && el[j].getAttribute("lazy_src")) { element_obj.push(el[j]); } } } for (var i = 0, len = element_obj.length; i < len; i++) { var o_img = element_obj[i]; var t_index = getAbsoluteTop(o_img); //得到圖片相對document的距上距離 if (map_element[t_index]) { map_element[t_index].push(i); } else { //按距上距離儲存一個隊列 var t_array = []; t_array[0] = i; map_element[t_index] = t_array; download_count++; //需要延時載入的圖片數量 } } }; function initDownloadListen() { if (!download_count) return; var offset = (window.MessageEvent && !document.getBoxObjectFor) ? doc_body.scrollTop : doc_element.scrollTop; //可視化地區的高=offtset+document的高 var visio_offset = offset + doc_element.clientHeight; if (last_offset == visio_offset) { setTimeout(initDownloadListen, 200);//每隔0.2秒檢測一次,這玩意兒感覺有些耗資源的 return; } last_offset = visio_offset; var visio_height = doc_element.clientHeight; var img_show_height = visio_height + offset; for (var key in map_element) { if (img_show_height > key) { var t_o = map_element[key]; var img_vl = t_o.length; for (var l = 0; l < img_vl; l++) { element_obj[t_o[l]].src = element_obj[t_o[l]].getAttribute("lazy_src"); } delete map_element[key]; download_count--; } } setTimeout(initDownloadListen, 200); }; function getAbsoluteTop(element) { if (arguments.length != 1 || element == null) { return null; } var offsetTop = element.offsetTop; while (element = element.offsetParent) { offsetTop += element.offsetTop; } return offsetTop; } function init(tags) { initVar(tags); initElementMap(); initDownloadListen(); }; return { init: init } })(); </script><style type="text/css">img{height:800px}</style></head><body> <div> <img lazy_src="http://pic.vlike.com/girl/UploadFiles_9401/201005/13/2010051307474029890_big.jpg" /><br/> <img lazy_src="http://pic.vlike.com/girl/UploadFiles_9401/201005/13/2010051307474372951_big.jpg" /><br/> <img lazy_src="http://pic.vlike.com/girl/UploadFiles_9401/201005/06/2010050616595471474_big.jpg" /><br/> <img lazy_src="http://pic.vlike.com/girl/UploadFiles_9401/201005/13/2010051307474693772_big.jpg" /><br/> <img lazy_src="http://pic.vlike.com/girl/UploadFiles_9401/201005/05/2010050511370456961_big.jpg" /><br/> <img lazy_src="http://pic.vlike.com/girl/UploadFiles_9401/201005/13/2010051311000442310_big.jpg" /><br/> </div> <script type="text/javascript"> lazyLoad.init(); </script></body></html>
注意事項:圖片最好都用樣式定義高度,否則圖片的高度預設為0,就上面的例子來講,所有img標籤都擠在一起,全部在第一屏,導致程式認為它們都應該載入,就看不到效果了.
另外這種方式有一個致命的缺點:如果瀏覽器禁用了javascript,將會失效!所以使用前請先考慮清楚,或者在頁面上加一些提示(類似:“您的瀏覽器不支援javascript,頁面顯示可能不正常”之類)
附:firefox上快速禁用和啟用javascript的方法
如所示,在firefox地址欄裡輸入about:config,找到javascript:enabled,雙擊可切換true或false(即:啟用或禁用)
當然,園子裡的高手還有一篇更強大的ImagesLazyLoad 圖片消極式載入效果 推薦給想深入研究的朋友們看看。
此外,jQuery也一個專門實現延時載入的外掛程式jQuery.lazyload,也很方便。