图片懒加载原生js实现
demo1 图片懒加载
预备知识
判断条件:offsetTop<scrollTop+innerHeight && offsetTop>=scrollTop
- 原始版本
// 绑定滚动事件
window.addEventListener('scroll', function() {
lazyLoading()
});
function lazyLoading() {
let imgs = document.getElementsByTagName('img');
// 滚动过的高度
let bodyScrollHeight = document.body.scrollTop || document.documentElement.scrollTop;
// 窗口的高度
let windowHeight = window.innerHeight;
for (let i = 0; i < imgs.length; i++) {
// 图片相对于顶部的位置
let imgHeight = imgs[i].offsetTop
//判断是否到达加载区域
if (imgHeight < bodyScrollHeight + windowHeight && imgHeight >= bodyScrollHeight) {
setTimeout(function() {
imgs[i].setAttribute('src', imgs[i].getAttribute('data-src'))
}, 1000)
}
}
}
// 第一次执行
lazyLoading()
- 优化:
- 判断是否已经加载过
- 用array的api代替for循环
遇到了问题,imgs并不能用forEach函数遍历,是一个HTMLCollection,需要将其转换成数组
原理,slice浅拷贝返回一个新的数组。如果是基本数据类型,就不会影响到原来的。如果含有引用,则会影响(没有深拷贝)
// 绑定滚动事件
window.addEventListener('scroll', function() {
lazyLoading()
});
function lazyLoading() {
let imgs = document.getElementsByTagName('img');
// 滚动过的高度
let bodyScrollHeight = document.body.scrollTop || document.documentElement.scrollTop;
// 窗口的高度
let windowHeight = window.innerHeight;
//转换成数组
let newimgs = Array.prototype.slice.apply(imgs)
newimgs.forEach(img => {
// 图片相对于顶部的位置
let imgHeight = img.offsetTop
//判断是否到达加载区域
if (imgHeight < bodyScrollHeight + windowHeight && imgHeight >= bodyScrollHeight) {
//判断是否已经加载过
if (img.getAttribute('src') === img.getAttribute('data-src')) return;
//这个定时器是模拟网站加载速度
setTimeout(function() {
img.setAttribute('src', img.getAttribute('data-src'))
}, 1000)
}
});
}
// 第一次执行
lazyLoading()
- 性能优化:
- window.scroll每次滚动都会触发
- 解决方法:当页面停止滚动的时候,再去执行页面中的方法(节流)
// 绑定滚动事件
let timer;
window.addEventListener('scroll', function() {
console.log("scroll")
//节流 当停止滚动再执行 每一次执行都先把上一次的关闭
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
console.log("lazyloading")
lazyLoading()
}, 300)
});
function lazyLoading() {
let imgs = document.getElementsByTagName('img');
// 滚动过的高度
let bodyScrollHeight = document.body.scrollTop || document.documentElement.scrollTop;
// 窗口的高度
let windowHeight = window.innerHeight;
//转换成数组
let newimgs = Array.prototype.slice.apply(imgs)
newimgs.forEach(img => {
// 图片相对于顶部的位置
let imgHeight = img.offsetTop
//判断是否到达加载区域
if (imgHeight < bodyScrollHeight + windowHeight && imgHeight >= bodyScrollHeight) {
// 判断是否已经加载过
if (img.getAttribute('src') === img.getAttribute('data-src')) return;
setTimeout(function() {
img.setAttribute('src', img.getAttribute('data-src'))
}, 1000)
}
});
}
// 第一次执行
lazyLoading()
效果:
此源码地址:https://github.com/JoanneXu6677/js_demo