天貓首頁迷思之-jquery實現整個div的懶加載(2)-插件面向對象化-閉包和原型的實例

前文有簡單的實現了一個製做懶加載的方法,但其實以方法的形式作插件擴展性不強。那麼本文就來用面向對象的方法將其製做成一個真正的插件:jquery

我想要的最終的調用效果是:git

1 $(".loading").lazyLoadDiv_cc({
2      //自定義效果,可不填
3     "beginHeight":400,
4     "loadingBgClass":"loading",
5     "whenToLoad":"someIn"
6 });

分析一下,須要擴展jquery的實例如:$(".loading")的方法。插件確定要用到$這個方法。因此初步原型是:github

1 ;(function($){
2     $.fn.lazyLoad=function(this,options){
3          //處理代碼
4     };
5   })(jQuery);

你可能會問的問題:安全

  • 爲何前面加封號? 答:防止該插件以前的代碼忘記加封號。影響代碼解析;
  • 爲何使用匿名函數?答:寫js的一個原則是儘可能不要污染全局變量。插件若是足夠龐大,確定把全部屬性和方法都暴露給全局。因爲js中沒有語句的塊級做用域,因此這裏使用當即執行的匿名函數。將不須要暴露給全局,可是插件的邏輯要用到得部分代碼放到函數的局部做用域中。這樣就不會和其餘的插件命名衝突啦。
  • 爲何參數要傳jQuery?答:這裏其實不傳也不會報錯,可是爲了保證代碼的獨立性,傳一下其實更保險。相似window,document這種均可以傳進來。

tips:這裏見縫插針,說下jquery和jquery的原型。閉包

  1.$是什麼?app

  從jquery源碼開始分析:函數

      第一次出現jQuery:工具

  

  由圖得知,jquery是一個函數。函數的入參是selector和context,返回一個實例。性能

  So,$("#div2")是一個實例,擁有不少方法,方法大部分在jQuery原型裏面。this

 

  暴露給全局變量:

        

  可知$和jQuery實際上是同一個函數。

  

  2.$.fn是什麼?

  源碼中:

jQuery.fn = jQuery.prototype=$.fn

  因此它是jQuery和$對象的原型。在它裏面添加方法至關於$的實例(如$("#div1"))都能調用到。

---------------------------------------------我是一個分割線-------------------------------------------

言歸正傳,初步的模型並無用到面向對象的特性。當插件愈來愈龐大時,面向過程就會變得邏輯混亂,難於管理,難於擴展。so。我們再改一下

 1 ;(function($){
 2     var lazyloadPlugin=function(ele,opt){
 3         this.elements=ele?ele:$(".loading"),//若沒有第一個參數,默認獲取class爲loading的元素
 4         this.defaults={
 5             //參數的默認值
 6             "beginHeight":0,
 7             "howToLoad":"fadeIn",
 8             "loadingBgClass":"loading",//定義未加載前背景圖片的類名
 9             "whenToLoad":"allIn"//默認爲div所有在可視窗口內開始加載;其餘值:「someIn」
10         },
11         this.options=$.extend({},this.defaults,opt)
12     };
13     lazyloadPlugin.prototype={
14         bindLazy:function(){
15          //實現代碼
16         }
17     };
18     //以上至關於MVC中的模型層,不須要關心邏輯怎麼串起來
19     $.fn.lazyLoadDiv_cc=function(options){
20                //至關於MVC中的業務邏輯層,須要組織邏輯
21         var llp=new lazyloadPlugin(this,options);
22         return llp.bindLazy();
23     };
24 })(jQuery);
lazyloadPlugin是定義在匿名函數中的對象,除了調用lazyLoadDiv_cc方法,並無其餘方式可使用它。所以它的各類屬性和方法都很安全。特別是它的原型,由於實例沒有辦法改變原型,因此原型中的方法是不可修改的,很安全。經過這一層封裝,咱們只暴露出來了一個看似簡單的方法。卻實現了可擴展、獨立性強、保證性能的方法。1.可擴展性。  經過options入參,能夠實現不一樣用戶的需求。例如options中的whenToLoad字段,能夠經過定義不一樣的值,讓插件在不一樣的位置觸發懶加載。同時,options在構造函數中定義了默認值。更健壯。2.獨立性強  將大部分屬性封裝起來,經過匿名函數+閉包,讓代碼更簡潔安全3.保證性能   根據共享的放在原型中,不共享的放在構造函數中這一原則。將默認值都放在對象的構造函數中,而方法的實現放在原型中。方法部分的內存共享,提升性能。只是一個簡單的例子,就用到了原型、閉包、this、匿名函數等多個知識點,多多實踐比只看書真的好多啦。實現邏輯以後,網上有在線壓縮工具。所謂壓縮,只是把變量語義化的名字名字改成更短的,多行也改成了一行,文件體積確實是壓縮了,可是邏輯一點也沒少哦。本次插件地址:    壓縮後-https://github.com/HappyBangs/bang_plugins/blob/master/plugin_TmallLazyLoad/version2.0/lazyload_pcc.min.js   壓縮前-https://github.com/HappyBangs/bang_plugins/blob/master/plugin_TmallLazyLoad/version2.0/lazyload_pcc.js
相關文章
相關標籤/搜索