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

也可以根據自己自動配置。

demo下載鏈接。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM