zoukankan      html  css  js  c++  java
  • 懒加载:判断高度法与IntersectionObserver API法

    感谢阮一峰老师撰写的非常详细的教程

    实现的大致预览:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>图片懒加载</title>
        <style>
            img {
                display: block;
                width: 100%;
                margin-bottom: 20px;
            }
        </style>
    </head>
    <body>
        <img data-src="img/asher-ward-453238-unsplash.jpg" src="img/asher-ward-453238-unsplash.jpg" alt="">
        <img data-src="img/asher-ward-453238-unsplash.jpg" src="img/asher-ward-453238-unsplash.jpg" alt="">
        <img data-src="img/jay-mantri-4033-unsplash.jpg" alt="">
        <img data-src="img/jp-valery-734900-unsplash.jpg" alt="">
        <img data-src="img/ryan-searle-345035-unsplash.jpg" alt="">
        <img data-src="img/thomas-tixtaaz-119883-unsplash.jpg" alt="">
    </body>
    <script>
            var imgs = document.querySelectorAll('img');
    
            //offsetTop是元素与上一级父元素的距离,需要循环获取直到得到元素相对于页面顶部的距离(即使在可是区域外)
            function getTop(e) {
                var T = e.offsetTop;
                while(e = e.offsetParent) {
                    T += e.offsetTop;//当e=undefined,即获取到最顶层,退出循环
                }
                return T;
            }
    
            function lazyLoad(imgs) {
                var H = document.documentElement.clientHeight;//获取可视区域高度
                var S = document.documentElement.scrollTop || document.body.scrollTop;//是文档的scrollTop属性!
                for (var i = 0; i < imgs.length; i++) {
                    if (H + S > getTop(imgs[i])) {//见示意图
                        imgs[i].src = imgs[i].getAttribute('data-src');
                    }
                }
            }
    
            window.onload = window.onscroll = function () { //onscroll()在滚动条滚动的时候触发
                lazyLoad(imgs);
            }
    </script> 
    
    </html>

    这个方法很容易理解,并且兼容性也不错,但是有一个致命的缺点就是onscroll事件触发的太频繁了,很容易影响页面性能。

    因而考虑使用IntersectionObserver,这个api兼容性很差,需要谷歌51+。

     //使用交叉观察器进行实现  IntersectionObserver API
        var observer = new IntersectionObserver(
            function visible(eles){
                eles.forEach(function(ele){
                    ele.target.src = ele.target.getAttribute('data-src');//注意这里的ele是观察器对象,ele.target才是被观察的元素
                    console.log(ele.target);
                    // observer.unobserve(this);//取消观察
                })
    
        },{
            threshold:[0,0.1],//可见比例达到...时触发观察器的回调函数
            // root:document.documentElement//当元素在容器内滚动时的设定
        });
        //observe的参数是一个 DOM 节点对象。如果要观察多个节点,就要多次调用这个方法。
        //也就是说,不能使用document.querySelector('img')
        //这里参考了阮一峰老师的教程
        function query(selector){
            return Array.from(document.querySelectorAll(selector));
        };
        query('img').forEach(function(item){
            observer.observe(item);
        })
        
        //IntersectionObserver API 是异步的,不随着目标元素的滚动同步触发。
    
    // 规格写明,IntersectionObserver的实现,应该采用requestIdleCallback(),
    // 即只有线程空闲下来,才会执行观察器。这意味着,这个观察器的优先级非常低,只在其他任务执行完,浏览器有了空闲才会执行。
  • 相关阅读:
    octotree神器 For Github and GitLab 火狐插件
    实用篇如何使用github(本地、远程)满足基本需求
    PPA(Personal Package Archives)简介、兴起、使用
    Sourse Insight使用过程中的常使用功能简介
    Sourse Insight使用教程及常见的问题解决办法
    github 遇到Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts问题解决
    二叉查找树的C语言实现(一)
    初识内核链表
    container_of 和 offsetof 宏详解
    用双向链表实现一个栈
  • 原文地址:https://www.cnblogs.com/linbudu/p/11069886.html
Copyright © 2011-2022 走看看