本文详解利用JavaScript实现网页图片延时加载(懒加载)的方法。通过将图片src替换为自定义属性lazy_src,并在页面滚动时动态计算可视区域,将出现在视野内的图片src还原,从而减少初始加载资源。文章提供了完整的JS代码实现、初始化步骤以及处理动态内容切换时的图片加载解决方案,适用于提升页面加载速度和用户体验。
实现原理
实现原理
首先,将页面上所有需要延时加载的图片标签中的src属性修改为自定义属性lazy_src。
| <img lazy_src="图片路径" border="0"/> |
接着,在页面加载阶段,遍历所有包含lazy_src属性的元素,将其存入一个数组中。当用户滚动页面时,实时计算可视区域的顶部位置(top值)。对于延时加载数组中的图片,若其距离页面顶部的距离小于当前可视区域的顶部位置(即图片已进入可视范围),则将该图片的lazy_src值赋给src属性,从而触发图片加载。
代码实现与使用
代码实现
| 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; 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(all_element[key]); } } } 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); 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 } })(); |
使用方法:将页面上需要延时加载的图片src属性替换为lazy_src,并将上述JavaScript代码放置在body标签的最后位置。最后,调用lazyLoad.init()方法即可生效。
验证加载效果:可以使用Firebug等开发者工具检查图片,确认其是否在滚动进入可视区域时才进行加载。
动态内容处理
注意事项:
如果页面包含内容切换模块(如Tab页),切换时新内容中的图片可能不会自动加载。处理方法是在内容切换逻辑中单独处理图片加载,例如:
///切换内容的代码...
chlid.find("img[init_src]").each(function(){
$(this).attr("src",$(this).attr("init_src"));
$(this).removeAttr("init_src");
});