懒加载相关实现技术
对于页面有很多静态资源的情况下(比如网商购物页面),为了节省用户流量和提高页面性能,可以在用户浏览到当前资源的时候,再对资源进行请求和加载。
- 不仅仅局限于图片,包括组件,都是可以实现懒加载的。
实现原理
监控需要懒加载的组件,是否进入到用户视野内,如果进入到用户视野内,就触发方法。(如图片懒加载,就可以将data-url 中的地址赋值给 img元素)
实现方法
- 原生实现
<img style="width: 100px;height: 100px;background: aqua;position: absolute;top: 1300px" id="lanchong" src="" data-src="https://upload-images.jianshu.io/upload_images/10319049-09fed8253549a943.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="">
// js 代码
var imgs = document.getElementsByTagName("img")
function lazyload() {
var scrollTop = window.pageXOffset || document.documentElement.scrollTop || document.body.scrollTop;
var viewPortSize = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
for(var i=0; i<imgs.length; i++) {
var x =scrollTop+viewPortSize-imgs[i].offsetTop;
if(x>0){
imgs[i].src = imgs[i].getAttribute('data-src');
}
}
}
setInterval(lazyload,1000);
- jquery 实现
var $window = $(window);
var lazyImgs = document.getElementsByTagName("img")
// 定义事件函数:
var onScroll = function() {
// 获取页面滚动的高度:
var wtop = $window.scrollTop();
// 判断是否还有未加载的img:
if (lazyImgs.length > 0) {
// 获取可视区域高度:
var wheight = $window.height();
// 循环处理数组的每个img元素:
for(var i=0; i<lazyImgs.length; i++) {
// 判断您是否在可视范围内
if (lazyImgs[i].offsetTop - wtop < wheight) {
// 设置src属性:
lazyImgs[i].src = lazyImgs[i].getAttribute('data-src');
}
}
}
};
// 绑定事件:
$window.scroll(onScroll);
// 手动触发一次:
onScroll()
- IntersectionObserver API 实现
// html代码
<button onclick="openObserver()">开始</button>
<button onclick="closeObserver()">结束</button>
<div id="lanchong" style="width: 100px;height: 100px;background: aqua;position: absolute;top: 1300px">
<template>
<img src="https://upload-images.jianshu.io/upload_images/10319049-09fed8253549a943.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="">
</template>
</div>
// js代码
let io = new IntersectionObserver(lazyload,{}); // 第二个参数是一个配置参数
let lanchongelement = document.getElementById('lanchong');
function openObserver() {
io.observe(lanchongelement);
}
function closeObserver() {
io.unobserve(lanchongelement); // 删除监听元素
io.disconnect(); // 停止所有监听
}
function callbackfun(entries) {
console.log("callbackfun"+ entries);
console.log("rootBounds:");
console.log(entries[0].rootBounds);
console.log("intersectionRatio");
console.log(entries[0].intersectionRatio);
}
// 实现懒加载
function lazyload(entries) {
entries.forEach(function(change) {
if(entries[0].intersectionRatio>0){
var container = change.target;
var content = container.querySelector('template').content;
container.appendChild(content);
io.unobserve(container);
}
});
}
- jquery.lazyload.js 实现
// $("img").lazyload({
// placeholder : "img/grey.gif", //用图片提前占位
// // placeholder,值为某一图片路径.此图片用来占据将要加载的图片的位置,待图片加载时,占位图则会隐藏
// effect: "fadeIn", // 载入使用何种效果
// // effect(特效),值有show(直接显示),fadeIn(淡入),slideDown(下拉)等,常用fadeIn
// threshold: 200, // 提前开始加载
// // threshold,值为数字,代表页面高度.如设置为200,表示滚动条在离目标位置还有200的高度时就开始加载图片,可以做到不让用户察觉
// event: 'click', // 事件触发时才加载
// // event,值有click(点击),mouseover(鼠标划过),sporty(运动的),foobar(…).可以实现鼠标莫过或点击图片才开始加载,后两个值未测试…
// container: $("window"), // 可以省略对某容器中的图片实现效果
// // container,值为某容器.lazyload默认在拉动浏览器滚动条时生效,这个参数可以让你在拉动某DIV的滚动条时依次加载其中的图片
// failurelimit : 10 // 图片排序混乱时
// // failurelimit,值为数字.lazyload默认在找到第一张不在可见区域里的图片时则不再继续加载,但当HTML容器混乱的时候可能出现可见区域内图片并没加载出来的情况,failurelimit意在加载N张可见区域外的图片,以避免出现这个问题.
// });
$(function() {
$("img").lazyload({effect: "fadeIn"});
});