资讯专栏INFORMATION COLUMN

A: 如何实现 Lazy Load?

Miyang / 2629人阅读

摘要:最近面试了几家公司,他们不约而同都问到了这个问题了解吗其实是对图片的一种延迟加载技术,直到用户滚动图片出现在用户可视范围时才把它加载出来。我在上亲身实践了一下,然而发现,总是返回,其他两种方法都正常获取到了值。

最近面试了几家公司,他们不约而同都问到了这个问题:了解 Lazy Load 吗?

Lazy Load is delays loading of images in long web pages. Images outside of viewport are not loaded until user scrolls to them. This is opposite of image preloading.

Using Lazy Load on long web pages will make the page load faster. In some cases it can also help to reduce server load.

Lazy Load其实是对图片的一种延迟加载技术,直到用户滚动图片出现在用户可视范围时才把它加载出来。它与图片预加载技术完全相反,却都是为了提高用户体验而设计。

Lazy Load Plugin for jQuery - Mika Tuupola

jQuery的Lazy Load插件大家应该都有了解或者已经使用过了。下面是一个简单的栗子:

    
    
    $(function() {
        $("img.lazy").lazyload();//可以传入自定义的参数
    });

data-original属性值是我们想要显示的图片的URL,当用户滚动页面,图片出现在视线范围内时,替换img元素的src属性值为data-original属性值。

不过仅仅了解这些好像远远不够。我在网上查找了一些Lazy Load的实现原理,发现了以下的代码:

    // 原生JS实现方法
    

这位老铁自己写了一段简陋的实现代码,他用了定时器循环调用lazyload方法,当然大家可以先忽略,重点看一下如何获取当前滚动条的位置和视口的高度。

    var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;

这个东西我刚看也是一头雾水。我在chrome上亲身实践了一下,然而发现,document.documentElement.scrollTop总是返回0,其他两种方法都正常获取到了值。于是查了一下才知道这三个获取滚动条位置的方法背后还有故事。看这个问题:

document.documentElement.scrollTop return value differs in Chrome

还有其中一位老铁的回答:

The standards-based way of getting the scroll is window.scrollY. This is supported by Chrome, Firefox, Opera, Safari and IE Edge or later. If you only support these browsers, you should go with this property.

IE >= 9 supports a similar property window.pageYOffset, which for the sake of compatibility returns the same as window.scrollY in recent browsers, though it may perhaps be deprecated at some point.

The problem with using document.documentElement.scrollTop or document.body.scrollTop is that the scroll needn"t be defined on either of these. Chrome and Safari define their scroll on the element whilst Firefox defines it on the element returned by document.documentElement, for example. This is not standardized, and could potentially change in future versions of the browsers. However, if the scrollY or pageYOffset are not present, this is the only way to get the scroll.

window.scrollY || window.pageYOffset || document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0)

那这故事我就不讲了。

    var viewportSize = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

这行代码是为了获取视口的高度,我们同样看到了三种方法,那他们背后肯定也有不为我知的故事,现在我也不太想知道了。

    var x =scrollTop+viewportSize-imgs[i].offsetTop;

如何获得一个元素与页面顶端的距离,你学会了吗?

下面是用jQuery实现的lazyload,也是刚才那位老铁写的:

    /**
    * 图片的src实现原理
    */
    $(document).ready(function(){
        // 获取页面视口高度
        var viewportHeight = $(window).height();
        var lazyload = function() {
            // 获取窗口滚动条距离
            var scrollTop = $(window).scrollTop();
            $("img").each(function(){
            // 判断 视口高度+滚动条距离 与 图片元素距离文档原点的高度         
            var x = scrollTop + viewportHeight - $(this).position().top;
            // 如果大于0 即该元素能被浏览者看到,则将暂存于自定义属性loadpic的值赋值给真正的src            
            if (x > 0)
            {
                $(this).attr("src",$(this).attr("loadpic")); 
            }
        })
        }
        // 创建定时器 “实时”计算每个元素的src是否应该被赋值
        setInterval(lazyload,100);
    });

上述的实现呢,我感觉还是可以说服我的,把定时器去掉,加入对滚动事件的侦听即可。不过,就这么草草了事好像也没什么意思,我下载了jQuery-lazyload的源码,准备研究一波。如果我看懂了什么,或者有什么收获,再来聊聊。

    /*!
     * Lazy Load - jQuery plugin for lazy loading images
     *
     * Copyright (c) 2007-2015 Mika Tuupola
     *
     * Licensed under the MIT license:
     *   http://www.opensource.org/licenses/mit-license.php
     *
     * Project home:
     *   http://www.appelsiini.net/projects/lazyload
     *
     * Version:  1.9.7
     *
     */
    (function($, window, document, undefined) {
      // body...
    })(jQuery, window, document);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82195.html

相关文章

  • react-lazy-load粗读

    摘要:粗读近来没什么特别要做的事,下班回来的空闲时间也比较多,所以抽空看看懒加载是怎么实现的,特别是看了下的库的实现。之先别关注,按他给注释说测试用。之是组件绑定事件时会触发的函数。 react-lazy-load粗读 近来没什么特别要做的事,下班回来的空闲时间也比较多,所以抽空看看懒加载是怎么实现的,特别是看了下 react-lazy-load 的库的实现。 懒加载 这里懒加载场景不是路由...

    dailybird 评论0 收藏0
  • SAP Fiori里的List是如何做到懒加载Lazy load的

    摘要:从调用栈能清楚发现是这个事件触发的第二批的读取动作。然后再去这一个调用栈,发现一个属性维护了一个开始索引,每次到底部的事件触发之后,该属性值都会被累加。这些库文件一览在开发者工具查看从后台加载的库文件,能发现属性在此处被硬编码成。 今天一同事问我这个问题:S/4HANA Fiori应用里的列表,一旦Scroll到底部就会自动向后台发起新的请求把更多的数据读取到前台显示。 以Produc...

    RyanQ 评论0 收藏0
  • SAP Fiori里的List是如何做到懒加载Lazy load的

    摘要:从调用栈能清楚发现是这个事件触发的第二批的读取动作。然后再去这一个调用栈,发现一个属性维护了一个开始索引,每次到底部的事件触发之后,该属性值都会被累加。这些库文件一览在开发者工具查看从后台加载的库文件,能发现属性在此处被硬编码成。 今天一同事问我这个问题:S/4HANA Fiori应用里的列表,一旦Scroll到底部就会自动向后台发起新的请求把更多的数据读取到前台显示。 以Produc...

    SolomonXie 评论0 收藏0
  • SAP Fiori里的List是如何做到懒加载Lazy load的

    摘要:从调用栈能清楚发现是这个事件触发的第二批的读取动作。然后再去这一个调用栈,发现一个属性维护了一个开始索引,每次到底部的事件触发之后,该属性值都会被累加。这些库文件一览在开发者工具查看从后台加载的库文件,能发现属性在此处被硬编码成。 今天一同事问我这个问题:S/4HANA Fiori应用里的列表,一旦Scroll到底部就会自动向后台发起新的请求把更多的数据读取到前台显示。 以Produc...

    Zhuxy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<