懒加载相关实现技术

对于页面有很多静态资源的情况下(比如网商购物页面),为了节省用户流量和提高页面性能,可以在用户浏览到当前资源的时候,再对资源进行请求和加载。

  • 不仅仅局限于图片,包括组件,都是可以实现懒加载的。

实现原理

监控需要懒加载的组件,是否进入到用户视野内,如果进入到用户视野内,就触发方法。(如图片懒加载,就可以将data-url 中的地址赋值给 img元素)

实现方法

  1. 原生实现
<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);
  1. 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()
  1. 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);
        }

    });
}
  1. 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"});
});