我爱编程

图片懒加载

2018-05-24  本文已影响7人  DHFE

在网页中,常常需要用到图片,而图片需要消耗较大的流量。正常情况下,浏览器会解析整个HTML代码,然后从上到下依次加载<img src="xxx">的图片标签。如果页面很长,隐藏在页面下方的图片其实已经被浏览器加载了。如果用户不向下滚动页面,就没有看到这些图片,相当于白白浪费了图片的流量。

所以,淘宝、京东这些流量非常巨大的电商,商品介绍页又必须有大量的图片,因此,这些页面的图片都是“按需加载”,即用户滚动页面时显示出来的时候才加载图片。当网速非常快的时候,用户并不能感知懒加载的动作,既省流量又不影响用户浏览。—— 廖雪峰 使用jQuery实现图片懒加载原理

基本思想是:在输出HTML的时候,不要直接输出<img src="xxx",而是将src的真正图片地址保存在data-src属性中。
当页面滚动时,如果图片出现在用户视野中,就利用jQuery把<img>的src属性替换为data-src的内容,浏览器就会实时加载。


1. 如何判断一个元素是否出现在窗口可视范围(浏览器的上边缘和下边缘之间,肉眼可视)。写一个函数 isVisible实现

原理示意图:

整个高度是document的高度,虚线代表用户浏览器视窗。
正方块和三角形代表了同一个元素的两种极值。
当一个元素由下至上进入用户视野,假设他刚好在视窗下方,此时会满足:target height(元素的offset) <= scrollTop + window height ,即滚动条已滚动的top值 + 窗口高度,只要target height 小于都可以,但大于的话,说明元素还是看不到,没有进入window。
另外一个情况就是,target height也必须大于scrollTop,否则也是没有进入用户window。

检测函数:

        function isVisible($node) {
            var scrollTop = $(window).scrollTop();  // 获取滚动条滚动高度
            var windowHeight = $(window).height();  // 获取视窗高度
            var offsetTop = $img.offset().top;      // 获取元素相对整个文档的高度

            if (offsetTop < scrollTop + windowHeight && offsetTop > scrollTop) {
                return true;
            }
            return false;
        }
2. 当窗口滚动时,判断一个元素是不是出现在窗口可视范围。每次出现都在控制台打印 true

测试代码:

<body>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>333</h1>
<h1><img id="test_img" src="./img/img1.jpg" alt=""></h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>
<h1>222</h1>

</body>
<script>
        $(window).on("scroll",function() {
            $("#test_img").each(function() {    // 对元素使用isVisible()检测
                if (isVisible($(this))) {
                    console.log(true);
                }
            })
        })



        function isVisible($node) {
            var scrollTop = $(window).scrollTop();  // 获取滚动条滚动高度
            var windowHeight = $(window).height();  // 获取视窗高度
            var offsetTop = $node.offset().top;      // 获取元素相对整个文档的高度

            if (offsetTop < scrollTop + windowHeight && offsetTop > scrollTop) {
                return true;
            }
            return false;
        }
</script>

4. 当窗口滚动时,判断一个元素是不是出现在窗口可视范围。在元素第一次出现时在控制台打印 true,以后再次出现不做任何处理。
    $(".img img").attr("sign","false");
        $(window).on("scroll",function() {
            $(".img img").each(function() {    // 对元素使用isVisible()检测
                if (isVisible($(this)) && $(this).attr("sign") === "false") {

                    $(this).attr("sign","true");
                    console.log(true);

                }
            })
        })



        function isVisible($node) {
            var scrollTop = $(window).scrollTop();  // 获取滚动条滚动高度
            var windowHeight = $(window).height();  // 获取视窗高度
            var offsetTop = $node.offset().top;      // 获取元素相对整个文档的高度

            if (offsetTop < scrollTop + windowHeight && offsetTop > scrollTop) {
                return true;
            }
            return false;
        }

上一篇下一篇

猜你喜欢

热点阅读