• 图片延迟加载的实现


     

    图片延迟加载也称懒加载,通常应用于图片比较多的网页,如果一个页面图片比较多,且页面高度或宽度有好几屏,页面初次加载时,只显示可视区域的图片,当页面滚动的时候,图片进入了可视区域再进行加载,这样可以显著的提高页面的加载速度,更少的图片并发请求数也可以减轻服务器的压力。如果用户仅仅在首屏停留,还可以节省流量。如果TAB中的图片较多,也同样可以应用于TAB中,当触发TAB时再进行图片的加载。

    图片延迟加载的原理比较简单,先将图片的真实地址缓存在一个自定义的属性(lazy-src)中,而src地址使用一个1×1的全透明的占位图片来代替,当然占位图片也可以是其他的图片。

    1 <img src="images/placeholder.png"  lazy-src="images/realimg.jpg" />

    因为是使用javascript来加载图片,如果用户禁用了javascript,可以设置一个替代的方案。

    1 <img src="images/placeholder.png"  lazy-src="images/realimg.jpg" alt="" />
    2 <noscript><img src="images/realimg.jpg"  alt="" /></noscript>

    页面初次加载时获取图片在页面中的位置并缓存(每次取offset的值会引发页面的reflow),计算出可视区域,当图片的位置出现在可视区域中,将src的值替换成真实的地址,此时图片就开始加载了。

    当页面滚动的时候,再判断图片已经缓存的位置值是否出现在可视区域内,进行替换src加载。当所有的图片都加载完之后,将相应的触发事件卸载,避免重复操作引起的内存泄漏。将整个窗口看成是一个大容器,那么也可以在页面中设置一个小容器,在小容器中也同样可以实现图片的延迟加载。

    下面是实现的代码,我写成了jQuery插件。

    001 (function( $ ){
    002 $.fn.imglazyload = function( options ){
    003     var o = $.extend({
    004                 attr        :   'lazy-src',
    005                 container   :   window,
    006                 event       :   'scroll',              
    007                 fadeIn      :   false,         
    008                 threshold   :   0, 
    009                 vertical    :   true   
    010             }, options ),
    011  
    012         event = o.event,
    013         vertical = o.vertical,
    014         container = $( o.container ),
    015         threshold = o.threshold,   
    016         // 将jQuery对象转换成DOM数组便于操作
    017         elems = $.makeArray( $(this) ),    
    018         dataName = 'imglazyload_offset',       
    019         OFFSET = vertical ? 'top' 'left',
    020         SCROLL = vertical ? 'scrollTop' 'scrollLeft',        
    021         winSize = vertical ? container.height() : container.width(),
    022         scrollCoord = container[ SCROLL ](),
    023         docSize = winSize + scrollCoord;
    024          
    025     // 延迟加载的触发器
    026     var trigger = {
    027  
    028         init : function( coord ){
    029             return coord >= scrollCoord &&
    030                             coord <= ( docSize + threshold );
    031         },
    032  
    033         scroll : function( coord ){
    034             var scrollCoord = container[ SCROLL ]();
    035             return coord >= scrollCoord &&
    036                     coord <= ( winSize + scrollCoord + threshold );
    037         },
    038          
    039         resize : function( coord ){
    040             var scrollCoord = container[ SCROLL ](),
    041                 winSize = vertical ?
    042                             container.height() :
    043                             container.width();
    044             return coord >= scrollCoord &&
    045                    coord <= ( winSize + scrollCoord + threshold );
    046         }
    047     };
    048          
    049     var loader = function( triggerElem, event ){
    050         var i = 0,
    051             isCustom = false,
    052             isTrigger, coord, elem, $elem, lazySrc;
    053                  
    054         // 自定义事件只要触发即可,无需再判断
    055         ifevent ){
    056             ifevent !== 'scroll' && event !== 'resize' ){
    057                 isCustom = true;
    058             }
    059         }
    060         else{
    061             event 'init';
    062         }
    063              
    064         for( ; i < elems.length; i++ ){ 
    065             isTrigger = false;
    066             elem = elems[i];
    067             $elem = $( elem );
    068             lazySrc = $elem.attr( o.attr );
    069              
    070             if( !lazySrc || elem.src === lazySrc ){
    071                 continue;
    072             }
    073             // 先从缓存获取offset值,缓存中没有才获取计算值,
    074             // 将计算值缓存,避免重复获取引起的reflow
    075             coord = $elem.data( dataName );
    076              
    077             if( coord === undefined ){
    078                 coord = $elem.offset()[ OFFSET ];
    079                 $elem.data( dataName, coord );
    080             }
    081  
    082             isTrigger = isCustom || trigger[ event ]( coord );         
    083  
    084             if( isTrigger ){
    085                 // 加载图片
    086                 elem.src = lazySrc;
    087                 if( o.fadeIn ){
    088                     $elem.hide().fadeIn();
    089                 }
    090                 // 移除缓存
    091                 $elem.removeData( dataName );
    092                 // 从DOM数组中移除该DOM
    093                 elems.splice( i--, 1 );
    094             }
    095         }
    096  
    097         // 所有的图片加载完后卸载触发事件
    098         if( !elems.length ){
    099             if( triggerElem ){
    100                 triggerElem.unbind( event, fire );
    101             }
    102             else{
    103                 container.unbind( o.event, fire );
    104             }
    105             $( window ).unbind( 'resize', fire );
    106             elems = null;
    107         }
    108          
    109     };
    110      
    111     var fire = function( e ){
    112         loader( $(this), e.type );
    113     };
    114      
    115     // 绑定事件
    116     container = event === 'scroll' ? container : $( this );
    117     container.bind( event, fire );
    118     $( window ).bind( 'resize', fire );
    119  
    120     // 初始化
    121     loader();
    122  
    123     return this;
    124 };
    125  
    126 })( jQuery );

    调用:

    1 $( 'img' ).imglazyload({
    2     event 'scroll',
    3     attr : 'lazy-src'
    4 });

    默认的调用可以省略所有参数。

    1 $( 'img' ).imglazyload();

    图片延迟加载的插件API说明:

    • attr string
    • 存放图片真实地址的属性名,与HTML对应,默认是lazy-src。
    • container dom & selector
    • 默认的容器为window,可自定义容器。
    • event stirng
    • 触发图片加载的事件类型,默认为window.onscroll事件
    • fadeIn boolean
    • 是否使用jQuery的fadeIn效果来显示,默认是false。
    • threshold number
    • 页面滚动到离图片还有指定距离的时候就进行加载,默认是0。
    • vertical boolean
    • 是否横向滚动,默认为true(纵向)。
    • loadScript(增强版的功能) boolean
    • 是否无阻塞加载javascript广告图片,默认为false。

    图片延迟加载的插件下载地址:http://stylechen.com/wp-content/uploads/download/imglazyload.zip

    原载于:雨夜带刀's Blog
    本文链接:http://stylechen.com/imglazyload2.html
    如需转载请以链接形式注明原载或原文地址。
  • 相关阅读:
    CF459E Pashmak and Graph
    cf478D Red-Green Towers
    cf255C Almost Arithmetical Progression
    准备做,但是还没做的
    CF219C hoosing Capital for Treeland
    最小中间和
    【NO.9】jmeter
    【设计用例】站内信
    【有意思的BUG】客户端无厘头 已连网的场景初始化太慢 未连网的场景异常崩溃
    禅道BUG系统
  • 原文地址:https://www.cnblogs.com/libin-1/p/5879403.html
Copyright © 2020-2023  润新知