小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。 21
使用 JavaScript 懒加载的几种实现方案
html 模板代码
懒加载就是不在一次加载过程中 同时 加载所有的元素的资源, 比如图片等显示内容, 而是在需要看到的时候动态的加载, 以减少资源的消耗, 和页面的卡顿等待时间问题.
注: 这里的模板还使用同一个
<body>
<div class="container">
<img
src=""
data-src="./img/img-1.jpg"
alt="loading-image 懒加载实现 图片"
loading="lazy"
class="my-photo"
/>
<img
src=""
data-src="./img/img-2.jpg"
alt="loading-image 懒加载实现 图片"
loading="lazy"
class="my-photo"
/>
<img
src=""
data-src="./img/img-3.jpg"
alt="loading-image 懒加载实现 图片"
loading="lazy"
class="my-photo"
/>
<img
src=""
data-src="./img/img-4.jpg"
alt="loading-image 懒加载实现 图片"
loading="lazy"
class="my-photo"
/>
<img
src=""
data-src="./img/img-5.jpg"
alt="loading-image 懒加载实现 图片"
loading="lazy"
class="my-photo"
/>
</div>
</body>
JavaScript 来实现懒加载代码逻辑:
这里 在代码中给出具体实现思路及说明:
实现方案 三
/// 实现方案 三
var imgs = document.body.querySelectorAll('img'),
H = window.innerHeight //浏览器视窗高度
function lazyload() {
var S = document.documentElement.scrollTop || document.body.scrollTop //滚动条滚过高度
;[].forEach.call(imgs, function (img) {
if (!img.getAttribute('data-src')) {
return
} //已经替换过的跳过
// if (H + S - 200 > getTop(img)) { //为达到演示效果,这里H+S减去200,延后加载时机
if (H + S > getTop(img)) {
//为达到演示效果,这里H+S减去200,延后加载时机
img.src = img.getAttribute('data-src')
img.removeAttribute('data-src')
}
})
;[].every.call(imgs, function (img) {
return !img.getAttribute('data-src')
}) && window.removeEventListener('scroll', lazyload, false) //完成所有替换后注销事件
}
window.addEventListener('scroll', lazyload, false)
window.addEventListener('load', lazyload, false)
function getTop(e) {
var T = e.offsetTop
while ((e = e.offsetParent)) {
T += e.offsetTop
}
return T
}
实现方案 四
/// 实现方案 四
function isInSight(el){
const bound = el.getBoundingClientRect();
const clientHeight = window.innerHeight;
// 如果只考虑向下滚动加载
// const clientWidth = window.innerWeight;
return bound.top <= clientHeight + 100;
}
function checkImgs() {
const imgs = document.querySelectorAll('.my-photo');
Array.from(imgs).forEach(el => {
if (isInSight(el)) {
loadImg(el);
}
})
}
function loadImg(el) {
if (!el.data-src) {
const source = el.dataset.data-src;
el.data-src = source;
}
}
function throttle(fn, mustRun = 500) {
const timer = null;
let previous = null;
return function() {
const now = new Date();
const context = this;
const args = arguments;
if (!previous){
previous = now;
}
const remaining = now - previous;
if (mustRun && remaining >= mustRun) {
fn.apply(context, args);
previous = now;
}
}
}