zoukankan      html  css  js  c++  java
  • JS图片延迟加载分析及简单的demo

    JS图片延迟加载

           图片延迟加载也称 "懒加载",通常应用于图片比较多的网页,比如 "美丽说首页","蘑菇街"等一些导购网站上用的比较多,或者淘宝,京东等电子商务网站上也用的比较多,因为页面加载时候 假如我们没有用延迟加载的话 那么页面上很多图片,首先要发n多个请求,性能肯定不怎么好,而我们用延迟加载技术,页面打开时候 只加载第一屏数据,第二屏以上都用延迟加载 滚动的时候进行加载,这样的话 假如页面不管他有n屏的话 那么我们只管加载第一屏的数据,后面不做操作。这样就可以显著的提高页面的加载速度,提升用户体验。且更小的并发请求也可以减轻服务器的压力,而且如果用户只浏览首屏的话,还可以节省流量(手机客户端应该用的比较多,减少用户流量)。

    延迟加载的原理是?

          我这边原理是先在img src中放一张占位符图片,而真实的图片地址存放在相对应一个属性 data-img(后缀img可以自定义)中,这样的话 那么页面加载的时候 只加载src地址 不会对属性的图片真正地址加载,滚动时候判断 待加载的资源相对于浏览器顶端的距离 <= 可视区域相对于浏览器顶端的距离 如果为true的话 则把相对应的data-img值赋值给src 否则不加载。

    先看看JSFiddle的demo效果

     如果最外层容器是window的话 那么请看这个demo  demo链接

     如果自己定义了最外层容器的话 那么请看这个demo demo链接 

    可配置的参数如下:

       container  window,容器 默认为window
     threshold  灵敏度。默认为 0 表示当图片出现在显示区域中的立即加载显示;设为整数表示图片距离 x 像素进入显示区域时进行加载;设为负数表示图片进入显示区域 x 像素时进行加载。
     event  默认为scroll(滚动)
     effect   默认为fadeIn 也可以为fadeIn, slideDown 等 jQuery 自带的效果
     effectspeed  1000,   effect的时间 默认为1000(毫秒)
     suffix  'img', img属性 默认以data-img 也可以自定义后缀
    skip_invisible   如果img标签为隐藏的 那么不强制加载(比如display:none等) 默认为true

    代码简单的分析下:

      1.页面初始化init时候 只处理一个滚动事件:如下调用update方法

    复制代码
    init: function(options){
        this.config = $.extend(this.config, options || {});
        var self = this,
            _config = self.config,
            _cache = self.cache;
        // 滚动时(或者其他事件) 触发事件
        $(_config.container).unbind(_config.event);
        $(_config.container).bind(_config.event,function(){
            self._update();
        });
    }
    复制代码

      2.update方法先判断下 容器是否是window还是自定义容器。且对向下滚动及向右滚动进行了一下处理。接着调用_eachImg这个方法。代码如下:

    复制代码
    _update:function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;
         if(_config.container === window) {
                 
             $('img').each(function(index,item){
                // 如果图片隐藏的 那么不强制加载
                if(_config.skip_invisible && !$('img').is(":visible")) {
                    return;
                }
                if (self._abovethetop(item) ||
                    self._leftofbegin(item)) {
                        // 什么都不处理
                } else if (self._belowthefold(item) &&
                    self._belowthefold(item)) {
                        self._eachImg(item);
                } 
            })
                
        }else {
                $('img',$(_config.container)).each(function(index,item){
                // 如果图片隐藏的 那么不强制加载
        if(_config.skip_invisible && !$('img').is(":visible")) {
                return;
        }
        if (self._abovethetop(item) ||
                self._leftofbegin(item)) {
                            
            } else if (self._belowthefold(item) &&
                    self._rightoffold(item)) {
                        self._eachImg(item);
                    } 
    
                })
             }
             
        },
    复制代码

      3.在调用eachImg方法之前 先判断向下滚动或者向右滚动 元素是否在可视区域内 如在 则调用eachImg方法 把对应的data-img赋值给src 否则 反之。

    HTML代码如下:

    复制代码
    <img src="images/grey.gif" data-img ="http://m3.img.libdd.com/farm4/d/2014/0111/18/3256C6587D94BDF9E9908908CAB6C5FD_B500_900_500_375.jpeg" width="800" height="600" isload="false"><br/>
        <img src="images/grey.gif" data-img ="http://m3.img.libdd.com/farm4/d/2014/0111/18/23CC5BDD3730A819E498B703A40DE5CF_B250_400_250_187.jpeg" width="800" height="600" isload="false"><br/>
        <img src="images/grey.gif" data-img ="http://m3.img.libdd.com/farm4/d/2014/0111/18/33F69B61E6671E4F6623F0D1084C42A8_B250_400_250_187.jpeg" width="800" height="600" isload="false"><br/>
        <img src="images/grey.gif" data-img ="http://m3.img.libdd.com/farm5/d/2014/0111/18/7B87F0A2209D234D2AB907C62946A7FE_B250_400_250_187.jpeg" width="800" height="600" isload="false"><br/>
        <img src="images/grey.gif" data-img ="http://m2.img.libdd.com/farm5/d/2014/0111/18/C37405D8DBC8D1BF69A9C894C32FA4DA_B250_400_250_187.jpeg" width="800" height="600" isload="false"><br/>
        <img src="images/grey.gif" data-img ="http://m1.img.libdd.com/farm5/d/2014/0111/18/1433297A651DA0329E866FD2D2776C7F_B250_400_250_187.jpeg" width="800" height="600" isload="false">
    复制代码

    JS所有代码如下:

    复制代码
    /**
     * JS图片延迟加载
     * @constructor {DataLazyLoad}
     * @param {options} 对象传参
     * @time 2014-1-10
     */
    /*
     * 延迟加载的原理:滚动时:待加载的资源相对于游览器顶端的距离 - threshold <= 可视区域相对于浏览器顶端的距离 true 就加载
     * 否则的话 不加载
     */
     function DataLazyLoad(options){
        
        this.config = {
    
            container      :   window,   //容器 默认为window
            threshold      :   0,        // 离多少像素渲染图片
            event          :  'scroll',  // 默认为scroll(滚动)
            effect         :  'fadeIn',  // 默认为fadeIn 也可以为fadeIn, slideDown 等 jQuery 自带的效果
            effectspeed    :  1000,      // 时间  
            suffix         :  'img',     // img属性 默认以data-img 也可以自定义后缀
            skip_invisible : true       // 如果img标签为隐藏的 那么不强制加载
        };
    
        this.cache = {};
    
        this.init(options);
     }
     
     DataLazyLoad.prototype = {
        
        init: function(options){
            
            this.config = $.extend(this.config, options || {});
            var self = this,
                _config = self.config,
                _cache = self.cache;
            
            // 滚动时(或者其他事件) 触发事件
            $(_config.container).unbind(_config.event);
            $(_config.container).bind(_config.event,function(){
                self._update();
            });
        },
        /*
         * 加载对应的图片
         */
        _eachImg: function(item) {
            var self = this,
                _config = self.config,
                _cache = self.cache;
            
            if($(item).attr('isload') == 'false') {
                var dataImg = $(item).attr('data-'+_config.suffix),
                    src = $(item).attr('src');
                 $(item).hide();
                 $(item).attr('src',dataImg);
                 $(item).attr('data-'+_config.suffix,'');
                 $(item)[_config.effect](_config.effectspeed);
                 $(item).attr('isload','true');
            } 
        },
        _update:function(){
            var self = this,
                _config = self.config,
                _cache = self.cache;
             if(_config.container === window) {
                 
                 $('img').each(function(index,item){
                    // 如果图片隐藏的 那么不强制加载
                    if(_config.skip_invisible && !$('img').is(":visible")) {
                        return;
                    }
                    if (self._abovethetop(item) ||
                        self._leftofbegin(item)) {
                            // 什么都不处理
                    } else if (self._belowthefold(item) &&
                        self._belowthefold(item)) {
                            self._eachImg(item);
                    } 
                })
                
             }else {
                $('img',$(_config.container)).each(function(index,item){
                    // 如果图片隐藏的 那么不强制加载
                    if(_config.skip_invisible && !$('img').is(":visible")) {
                        return;
                    }
                    if (self._abovethetop(item) ||
                        self._leftofbegin(item)) {
                            
                    } else if (self._belowthefold(item) &&
                        self._rightoffold(item)) {
                            self._eachImg(item);
                    } 
    
                })
             }
             
        },
        /*
         * 往下滚动时 判断待加载的元素是否在可视区域内
         * @return {Boolean}
         */
        _belowthefold: function(elem){
            var self = this,
                _config = self.config;
            var fold;
            if(_config.container === window) {
                fold = $(window).height() + $(window).scrollTop();
            }else {
                fold = $(_config.container).offset().top + $(_config.container).height();
            }
    
            return fold >= $(elem).offset().top - _config.threshold;
        },
        /* 
         * 往右滚动时 判断待加载的元素是否在可视区域内
         * @return {Boolean}
         */
        _rightoffold: function(elem){
            var self = this,
                _config = self.config;
            var fold;
            if(_config.container === window) {
                fold = $(window).width() + $(window).scrollLeft();
            }else {
                fold = $(_config.container).offset().left + $(_config.container).width();
            }
            
            return fold >= $(elem).offset().left - _config.threshold;
        },
        /*
         * 往上滚动
         * @return {Boolean}
         */
        _abovethetop: function(elem){
            var self = this,
                _config = self.config;
            var fold;
            if(_config.container === window) {
                fold = $(window).scrollTop();
            }else {
                fold = $(_config.container).offset().top;
            }
            return fold >= $(elem).offset().top + _config.threshold  + $(elem).height();
        },
        /*
         * 往左滚动
         * @return {Boolean}
         */
        _leftofbegin: function(elem) {
            var self = this,
                _config = self.config;
            var fold;
            
            if (_config.container === window) {
                fold = $(window).scrollLeft();
            } else {
                fold = $(_config.container).offset().left;
            }
            return fold >= $(elem).offset().left + _config.threshold + $(elem).width();
        }
        
     };
    
     // 初始化的方式
     $(function(){
        
        var datalazy = new DataLazyLoad({
            container: '#demo'
        });
     });
    复制代码

    初始化方式如下:

    // 初始化的方式
     $(function(){
        var datalazy = new DataLazyLoad({
            container: '#demo'
        });
     });

    也可以根据自己自动配置。

    demo下载链接。

  • 相关阅读:
    作业,注册页面
    HTML表单
    用HTML制作简历
    多线程同步标记
    集合类
    多态 接口
    java 泛型讲解
    转型
    使用super关键字
    作业题
  • 原文地址:https://www.cnblogs.com/yxlblogs/p/3522101.html
Copyright © 2011-2022 走看看