懒加载原理

对于页面有很多静态资源的情况下(比如商品图),为了节省用户流量和提高页面性能,可以在用户浏览到当前资源的时候,再对资源进行请求和加载,不仅可以减轻服务器的压力,而且用户体验也好一点

方式1:通过scroll监听滚动,getBoundingClientRect获取位置信息,(这种方式缺点是经常计算元素位置信息,性能较差,可能给你的网站造成相当大的闪烁)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title></title>
    <style type="text/css">
        .box{margin-top:700px;}
        .box img{width:100%;height:270px;border:1px solid #ddd;}
    </style>
</head>
<body>
<div class="box">
    <img  data-src="https://test.jifenyi.com:9123/htmlPC/10060/images/pointA/banner.jpg" class="js_img">
    <img  data-src="https://test.jifenyi.com:9123/uxunimg2/cust/shop/17216/goods/pic/2018/09/11/25194778443592045449242.jpg_140x140c.jpg" class="js_img" >
    <img  data-src="https://test.jifenyi.com:9123/uxunimg2/cust/shop/17216/goods/pic/2018/09/11/951689489805364494.jpg_140x140c.jpg" class="js_img" >
    <img  data-src="https://test.jifenyi.com:9123/uxunimg2/cust/shop/17216/goods/pic/2018/09/11/8198878495038442.jpg_140x140c.jpg" class="js_img">
</div>
<script type="text/javascript">
    var h = document.documentElement.clientHeight; // 视口高度
    var js_imgAll = document.querySelectorAll('.js_img')
    var flag = 0; // 记录已经加载过的图片

    window.onload = uploadImg
    window.onscroll = _throttle(uploadImg, 300)

    // 检查未加载的图片
    function uploadImg() {
        for(var i = flag; i < js_imgAll.length; i++) {
            if(_isShow(js_imgAll[i])) {
                _replacePath(js_imgAll[i])
                flag = i
            }
        }
    }

    // 是否将显示图片
    function _isShow(img) {
        // getBoundingClientRect获取图片大小以及位置
        var obj_t = img.getBoundingClientRect().top
        // 100是为了预加载
        if(obj_t <= h + 100) {
            return true
        }
        return false
    }

    // 替换图片路径
    function _replacePath(obj) {
        if(!obj.src) {
            obj.src = obj.getAttribute('data-src')
        }
        
    }

    // 函数节流,滚动条滚动等频繁的DOM操作,让一个函数不要执行的太频繁,减少一些过快的调用来节流
    function _throttle(fn, t) {
        var flag = true;
        return function () {
            if(!flag) return;
            flag = false;
            setTimeout(() => {
                fn.apply(this, arguments)
                flag = true;
            }, t)

        }
    }
</script>
</body>
</html>

 方式2:通过IntersectionObserver,它可以检测一个元素是否可见,能让你知道一个被观测的元素什么时候进入或离开浏览器的视口(目前ios不兼容)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title></title>
    <style type="text/css">
        .box{margin-top:700px;}
        .box img{width:100%;height:270px;border:1px solid #ddd;}
    </style>
</head>
<body>
<div class="box">
    <img  data-src="https://test.jifenyi.com:9123/htmlPC/10060/images/pointA/banner.jpg" class="js_img">
    <img  data-src="https://test.jifenyi.com:9123/uxunimg2/cust/shop/17216/goods/pic/2018/09/11/25194778443592045449242.jpg_140x140c.jpg" class="js_img" >
    <img  data-src="https://test.jifenyi.com:9123/uxunimg2/cust/shop/17216/goods/pic/2018/09/11/951689489805364494.jpg_140x140c.jpg" class="js_img" >
    <img  data-src="https://test.jifenyi.com:9123/uxunimg2/cust/shop/17216/goods/pic/2018/09/11/8198878495038442.jpg_140x140c.jpg" class="js_img">
</div>
<script type="text/javascript">
    var js_imgAll = document.querySelectorAll('.js_img')
    
    // IntersectionObserver是浏览器提供的构造函数,callback是可见性变化时的回调函数
    var io = new IntersectionObserver(entries => {
        entries.forEach(item => {
            // 目标元素的可见比例大于0即出现在可视区
            if(item.intersectionRatio > 0) {
                // 替换路径
                _replacePath(item.target)
                // 停止观察图片
                io.unobserve(item.target)
            }
        })
    })
    

    // 开始观察每个图片
    Array.from(js_imgAll).forEach(obj => {
         io.observe(obj)
    })
    

    // 替换图片路径
    function _replacePath(obj) {
        if(!obj.src) {
            obj.src = obj.getAttribute('data-src')
        }
        
    }
</script>
</body>
</html>
原文地址:https://www.cnblogs.com/hesj/p/10523152.html