博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS图片延迟加载分析及简单的demo
阅读量:7071 次
发布时间:2019-06-28

本文共 7457 字,大约阅读时间需要 24 分钟。

JS图片延迟加载

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

延迟加载的原理是?

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

先看看JSFiddle的demo效果

 如果最外层容器是window的话 那么请看这个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代码如下:

View Code

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'    }); });
View Code

初始化方式如下:

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

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

 

转载地址:http://nozml.baihongyu.com/

你可能感兴趣的文章
CentOS 开机启动
查看>>
ASP.NET Core的身份认证框架IdentityServer4(5)- 包和构建
查看>>
查看本机的ip地址
查看>>
select点击option获取文本输入框的焦点事件
查看>>
setup 命令中防火墙配置选项无法打开
查看>>
kaptcha验证码
查看>>
Centos6下编译LEDE/OpenWrt
查看>>
kubernetes入门(08)kubernetes单机版的安装和使用
查看>>
SonarQube代码质量管理平台 的安装、配置与使用
查看>>
docker~run起来之后执行多条命令
查看>>
Linux下通过受限bash创建指定权限的账号
查看>>
php:使用XHProf查找PHP性能瓶颈
查看>>
Ubuntu单用户模式(安全模式)
查看>>
Python之反射练习
查看>>
[MST] Describe Your Application Domain Using mobx-state-tree(MST) Models
查看>>
6. python 字符串格式化表达式
查看>>
【BIEE】11_BIEE图形报表在谷歌浏览器64.0.3282.140中访问图例乱码解决
查看>>
【java】java 中 byte[]、File、InputStream 互相转换
查看>>
Beta分布从入门到精通
查看>>
[LeetCode] Redundant Connection II 冗余的连接之二
查看>>