图片懒加载:滑动页面到能看到图片的时候再加载图片; 核心思路: 1、判断图片是否出现在视口中,即 什么时候显示图片; 2、控制图片显示; 本文完整源代码地址:https://gitee.com/duanweidong/interview-question-code.git
方案一:位置计算 滚动事件 (Scroll) DataSet API
1、判断图片是否出现在当前视口:
clientTop
,offsetTop
,clientHeight
以及 scrollTop
等各种距离高度做对比,利用scroll事件,节流判断图片的位置;
2、控制图片的加载显示:
代码语言:javascript复制<div class="container">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
</div>
首先设置一个临时 Data 属性 data-src
,控制加载时使用 src
代替 data-src
,可利用 DataSet API 实现。
核心代码
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<div class="container">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
<img src="loading.gif" data-src="pic.png">
</div>
<script>
var imgs = document.querySelectorAll('img');
function lozyLoad(){
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
var winHeight= window.innerHeight;
for(var i=0;i < imgs.length;i ){
if(imgs[i].offsetTop < scrollTop winHeight ){
imgs[i].src = imgs[i].getAttribute('data-src');
}
}
}
window.onscroll = lozyLoad();
</script>
</html>
方案二:
getBoundingClientRect API Scroll with Throttle DataSet API
1、判断图片是否出现在当前视口:
利用 Element.getBoundingClientRect()
方法返回元素的大小及其相对于视口的位置。
// clientHeight 代表当前视口的高度
img.getBoundingClientRect().top < document.documentElement.clientHeight;
外加节流实时判断图片位置;
2、控制图片加载同方案一;
核心代码
代码语言:javascript复制<script>
let viewHeight = document.body.clientHeight;
const demo = document.querySelectorAll("img");
function lazy() {
for (let elem of demo) {
if (
elem.getBoundingClientRect().top <
document.documentElement.clientHeight
) {
if (elem.dataset.src && elem.src == "") {
elem.src = elem.dataset.src;
}
}
}
}
function throttle(t, fn) {
let time;
return function () {
if (!time) {
time = setTimeout(() => {
time = null;
fn();
}, t);
}
};
}
lazy();
window.addEventListener("scroll", throttle(500, lazy));
</script>
方案三:IntersectionObserver API DataSet API
1、判断图片是否出现在当前视口:
使用浏览器IntersectionObserver
api, 可以监听元素是否与浏览器视口有交叉,也叫交叉观察器;该api存在兼容性chrom51 以上才能看到效果;
2、控制图片加载同方案一;
核心代码
代码语言:javascript复制<script>
const images = document.querySelectorAll('img');
// 新的 api IntersectionObserver
const observer = new IntersectionObserver((changes) => {
changes.forEach(change => {
if (change.isIntersecting) {
const img = change.target
img.dataset.src && img.src == "" && (img.src = img.dataset.src)
observer.unobserve(img)
}
})
})
images.forEach(img => observer.observe(img))
</script>
方案四:LazyLoading 属性
直接将懒加载的事交给浏览器做只需要加上该属性即可;
代码语言:javascript复制<img src="shanyue.jpg" loading="lazy" />
vue中使用懒加载
安装 vue-lazyload 插件 ,具体使用方法可按插件说明;