前言
为什么要使用图片懒加载?
当我们做一个商城项目,那么首页会加载不可预计的商品数量,也就是图片;有的图片甚至可以达到600KB-900KB,当图片数量很多的时候,首页就会加载很慢,会直接影响到用户的体验。
像类似这种图片过多的页面,我们可以通过图片懒加载Lazyload对图片进行处理,减轻页面的加载负担。图片懒加载的思路是将页面内的图片未出现在浏览器的可视区域的图片先不做加载,等到图片滚动到浏览器的可视区域后,再去做加载。这样即提高首页加载性能,也提高了用户的体验感。
思路
先将图片地址使用 data-src
属性保存起来,src
属性就用默认的;
<img data-src="https://img.png" src="placeholder.png" />
检测图片是否出现在浏览器的可视区域,这里介绍两种做法:
plan A
利用滚动事件 scroll
监听窗口元素
window.addEventLister('scroll', function(){
// 事件监听
})
window.removeEventLister('scroll', function() {
// 事件卸载
})
页面加载时判断图片的offsetTop
是否出现在浏览器的可视区域,为true 时把img
标签data-src
属性赋值给src
,这样就达到了图片懒加载需求。
plan B
使用 Intersection Observer
Intersection Observer API提供了一种异步观察目标元素与祖先元素或顶级文档viewport的交集中的变化的方法。
这里就不做详细的概述了, Intersection Observer 点击查看API>
let options = {
root: document.querySelector('#scrollEl'),
rootMargin: '0px',
threshold: 1.0
}
let observer = new IntersectionObserver(callback, options)
function callback (entries, observer) {
entries.forEach(function(entry) {
// ....
})
}
实现
plan A 使用滚动事件 scroll 实现
HTML
<div class="doc">
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
</div>
css
.doc { width: 100%; }
img { width: 100%; }
js
window.onload = function () {
// 图片集合
let imgs = document.querySelectorAll('.img')
function init() {
imgs.forEach(function(item) {
// 浏览器窗口top位置
let windowTop = document.documentElement.clientTop
// 浏览器窗口高度
let windowHeight = document.documentElement.clienHeight
// 图片距离窗口的值
let imgsTop = item.getBoundingClientRect().top
// 详细说明请看大屏幕 ^-^
if (imgsTop - windowTop <= windowHeight) {
// 获取保存到data-src 的图片地址
let src = item.getAttribute('data-src')
// 再设置他的src值
item.setAttribute('src', src)
}
})
}
// 初始化
init()
// 滚动监听
window.addEventerListener('scroll', init)
}
大屏幕
第一种方法已经实现完成, 有什么不对的地方,请各位大神指正 ^-^
plan B 使用 Intersection Observer
PS: 判断元素是否发生交集点实现
window.onload = function() {
// 图片集合
let imgs = document.querySelectorAll('.img')
const option = {
// root 目标元素的父级元素。如果未指定或者为null,则默认为浏览器视窗。
// root: '',
rootMargin: '0px',
threshold: 1.0
}
function init(target) {
// 有图为证 ^-^
const intersectionObserver = new IntersectionObserver(
function(entries, observer){
entries.forEach(function(entry){
// 当root 元素与目标元素相交 isIntersecting 为true,
if (entry.isIntersecting) {
// 获取保存到data-src 的图片地址
const src = entry.getAttribute('data-src')
// 再设置他的src值
entry.setAttribute('src', src)
// 断开连接
observer.disconnect()
}
}
}, option)
intersectionObserver.observer(target)
}
imgs.forEact(function(item) {
init(item)
}
}
^-^ 欢迎大神吐槽🙈