对于一些资源文件(图片等),只有真正用到的时候才去加载它(发请求),在这之前用体积更小的占位图替代。这么一来就为用户节省了不必要的流量开销。
就图片而言,只需要在用户看到或者即将看到的时候。把它 load 出来就可以了。所以这里需要判断图片容器是否进入了页面的可视区域 viewport。
为了达到上面那一 part 黑体字的目的,我们需要知道两个东西:
获取用户设备 viewport 的高度,如果需要兼容 IE,那么可以用 document.documentElement.clientHeight 作为备选。
这个方法非常有用,会返回一组“坐标”数据,MDN 给的定义是:
该方法的返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的 CSS 边框集合。DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right 和 bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
需要注意的是,这里的 top / right / bottom / left 的定义如下图:
所以,只需要判断 前者 - 后者 >= 0 就能说明相应的元素进入了屏幕的可视区域。
首先,我们的 DOM 结构是这样子的
<style>
.lazyload-img {
width: 200px;
height:200px;
background-size: cover;
background: url("https://kyrieliu.cn/placeholder.png");
}
</style>
...
<div class="lazyload-img" data-src="http://kyrieliu.cn/head.png"></div>
第一步,获取屏幕的高度
const screenHeight = window.innerHeight || document.documentElement.clientHeight;
第二步,获取相应图片容器元素距离 viewport 顶部的距离(假设只有一个图片),满足条件时开始加载真正的图片。
const img = document.querySelector('.lazyload-img');
function lazyload(){
let distance = screenHeight - img.getBoundingClientRect().top;
if (distance >= 0){
let src = img.getAttribute('data-src');
img.style.background = `url("${src}")`;
}
}
最后,添加滚动事件
window.addEventListener('scroll', lazyload, false);
Done.