原生JavaScript实现滚动图片懒加载(仿LazyLoad效果)
本文介绍如何使用原生JavaScript实现页面滚动图片懒加载功能,无需依赖jQuery。通过监听滚动事件、判断元素可视区域及兼容性处理滚动条位置,实现图片按需加载,从而减少HTTP请求,提升页面加载速度与用户体验。
引言与背景
本文撰写的初衷
这是一种优化页面的实用技术,实现难度较低;
查阅资料发现相关文章多依赖jQuery,本文旨在展示不依赖jQuery的实现方式;
技术分享有助于他人协助测试,因本人未在项目中实际应用,系个人研究,如有问题敬请指正;
本月博客尚未更新;
当前无工作任务,正是撰写的好时机;
滚动加载原理与优势
现代网页通常内容充实、图片众多,如淘宝、京东等电商网站,单页图片数量庞大,因此滚动动态加载成为流行方案。该方法能显著减少HTTP请求,仅加载可视区域图片,待滚动至特定位置时才加载后续图片,从而提升加载速度。《高性能网站建设指南》第一章强调了减少HTTP请求对前端性能优化及页面加载加速的重要性。
实现原理
核心原理:
1.为页面绑定滚动事件监听;
2.页面初始化时,将真实图片地址存储于特定属性中;
3.在滚动过程中,判断图片元素是否进入浏览器可视窗口;
4.执行图片加载,具体加载内容及用户体验由开发者自定义;
浏览器兼容性处理
技术难点:
浏览器兼容性是主要难点,涉及DOM标准与IE标准的差异,前端开发需频繁处理此类兼容性问题。以下代码片段供参考:
1.window.pageYOffset ? window.pageYOffset : window.document.documentElement.scrollTop
功能:获取当前页面相对于窗口显示区左上角的Y轴偏移量。
DOM标准实现:window.pageYOffset;
IE标准实现:window.document.documentElement.scrollTop
2.window.innerHeight ? window.innerHeight : document.documentElement.clientHeight
功能:定义窗口文档显示区的高度和宽度,单位为像素。
DOM标准:innerheight 和 innerwidth;
IE标准:document.documentElement 或 document.body(取决于DTD)的 clientWidth 和 clientHeight 属性
3.obj.getBoundingClientRect().top + window.document.documentElement.scrollTop + window.document.body.scrollTop
功能:获取页面元素相对于视口的位置。
非webkit内核浏览器中,document.body.scrollTop值恒为0,需使用 document.documentElement.scrollTop 获取正确值;
webkit内核浏览器中,document.documentElement.scrollTop值恒为0,需使用 document.body;
另有观点认为这与DTD相关(即指定DOCTYPE时使用 document.documentElement,未指定时使用 document.body),恳请知情者指正,不胜感激。
细节优化建议
实现细节:
1.由于真实地址初始存储于某属性(默认为xsrc,可自定义),建议默认图片地址使用1像素透明图片,以避免浏览器显示红叉;

2.图片加载过程中可添加占位图,以提供良好用户体验,前端开发始终追求此目标(示例中已体现);
3.图片加载成功后可添加合适的显示效果(示例中未体现,可自行尝试);
JavaScript源码实现
JavaScript源码如下:
代码示例:
var scrollLoad = (function (options) {
var defaults = (arguments.length == 0) ? { src: 'xSrc', time: 300} : { src: options.src || 'xSrc', time: options.time ||300};
var camelize = function (s) {
return s.replace(/-(\w)/g, function (strMatch, p1) {
return p1.toUpperCase();
});
};
this.getStyle = function (element, property) {
if (arguments.length != 2) return false;
var value = element.style[camelize(property)];
if (!value) {
if (document.defaultView && document.defaultView.getComputedStyle) {
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css.getPropertyValue(property) : null;
} else if (element.currentStyle) {
value = element.currentStyle[camelize(property)];
}
}
return value == 'auto' ? '' : value;
};
var _init = function () {
var offsetPage = window.pageYOffset ? window.pageYOffset : window.document.documentElement.scrollTop,
offsetWindow = offsetPage + Number(window.innerHeight ? window.innerHeight : document.documentElement.clientHeight),
docImg = document.images,
_len = docImg.length;
if (!_len) return false;
for (var i = 0; i < _len; i++) {
var attrSrc = docImg[i].getAttribute(defaults.src),
o = docImg[i], tag = o.nodeName.toLowerCase();
if (o) {
postPage = o.getBoundingClientRect().top + window.document.documentElement.scrollTop + window.document.body.scrollTop; postWindow = postPage + Number(this.getStyle(o, 'height').replace('px', ''));
if ((postPage > offsetPage && postPage < offsetWindow) || (postWindow > offsetPage && postWindow < offsetWindow)) {
if (tag === "img" && attrSrc !== null) {
o.setAttribute("src", attrSrc);
}
o = null;
}
}
};
window.onscroll = function () {
setTimeout(function () {
_init();
}, defaults.time);
}
};
return _init();
});
scrollLoad(); 参数配置说明
可传递参数以设置源地址属性名及响应延迟时间
调用示例:
scrollLoad({
src:'userSrc', //字符串类型
time: 100 //数字类型
}) 示例下载
tween.js 内存泄漏预防:怎么正确停止动画与清理对象
2026-11-05 15:52:56
Vue或React项目中为何不建议直接使用JS刷新页面
2026-11-05 13:57:30
哪里可以找到高质量的免费JS脚本资源?
2026-11-05 13:15:03
JS数组对象怎么根据指定ID字段去重
2026-11-04 21:41:10
JS数组去重方法性能对比:Set、Map与Filter谁更快
2026-11-04 16:14:15








