图片懒加载的两种实现方式
图片懒加载的原理就是将图片真实地址定义在img标签自定义属性上,img标签src设置为一张默认图片,(例如loading图片)当图片标签位于视口范围内时 将自定义属性上的图片地址 设为img标签的src即可。
监听滚动事件的方式
遍历文档中所有图片, 通过getBoundingClientRect().top获取每个图片元素距离文档顶部的高度, 如果图片元素top的值小于 clientHeight表示元素在可视区域内,这时候将自定义属性上的图片地址赋值给图片元素的src属性即可。需要监听scroll事件,进行节流处理以较少性能开支。
代码如下:
/**
* 滚动执行
*/
function handleScroll() {
var imgArr = document.querySelectorAll("img[data-src]");
var clientHeight = document.documentElement.clientHeight;
[].forEach.call(imgArr, function (item, index) {
if (item.getBoundingClientRect().top < clientHeight) {
item.src = item.getAttribute("data-src");
}
})
}
/**
* 节流
* @param time
* @param action
* @returns {Function}
*/
function throttle(time, action) {
var timer = null;
return function () {
var context = this;
var args = arguments;
if (!timer) {
timer = setTimeout(function () {
action.apply(context, args);
timer = null;
}, time);
}
}
}
handleScroll();
window.addEventListener("scroll", throttle(1000, handleScroll))
jquery版本:
function handleScroll() {
var imgArr = $("img[data-src]");
var bodyScrollHeight = $(document).scrollTop();
var wh = $(window).innerHeight();
for (var i = 0; i < imgArr.length; i++) {
var imgHeight = $(imgArr[i]).offset().top;//获取元素上边框相对于文档顶端的偏移量
if (imgHeight < bodyScrollHeight + wh && imgHeight >= bodyScrollHeight) {
$(imgArr[i]).attr('src', imgArr.eq(i).attr("data-src"));
}
}
}
通过IntersectionObserver API实现
通过监听scroll事件实现懒加载是非常消耗性能的,通过IntersectionObserver是监听目标元素与其祖先或视窗交叉状态的API,就是观察一个元素是否在视窗可见。
可以看到,交叉了就是说明当前元素在视窗里,当前就是可见的了。
IntersectionObserver就是一个构造函数,new 一个监视器:
var ob = new IntersectionObserver(callback, options)
ob实例的三个方法:
//对元素target添加监听,当target元素变化时,就会触发上述的回调
ob.observe(target);
// 移除一个监听,移除之后,target元素的可视区域变化,将不再触发前面的回调函数
ob.unobserve(target);
// 停止所有的监听
ob.disconnect();
我们获取文档中所有的图片并遍历他们传入每一个图片元素即可,当被观察的元素进入视窗 会触发callback
在callback中有entries参数,数组中的每一个元素,都是一个代表可视性变化的对象IntersectionObserverEntry,它包含元素的一些基本信息和变化的信息。
IntersectionObserverEntry 对象属性:
boundingClientRect 目标元素的矩形信息
intersectionRatio 相交区域和目标元素的比例值 intersectionRect/boundingClientRect 不可见时小于等于0
intersectionRect 目标元素和视窗(根)相交的矩形信息 可以称为相交区域
isIntersecting 目标元素当前是否可见 Boolean值 可见为true
rootBounds 根元素的矩形信息,没有指定根元素就是当前视窗的矩形信息
target 观察的目标元素
time 返回一个记录从IntersectionObserver的时间到交叉被触发的时间的时间戳
实现图片懒加载的代码如下:
function lazyLoad() {
var imgArr = document.querySelectorAll("img[data-src]");
var ob = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
//已经在视窗范围
if (entry.isIntersecting) {
var img = entry.target;
img.src = img.getAttribute("data-src");
}
})
});
[].forEach.call(imgArr, function (item, index) {
ob.observe(item);
});
}
lazyLoad();
版权声明:
作者:东明兄
链接:https://blog.crazyming.com/technology-sharing/2101/
来源:CrazyMing
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论