開發背景
本插件開發是近期寫的最后一個插件了,接下來我想把最近研究的redis最為一個系列闡述下。當然Jquery插件開發是我個人愛好,我不會停止,在將來的開發中我會繼續完善,當然也會堅持寫這個系列的。
每次開發我都會說一下開發插件中用的思想和自己在開發時候的想法。這篇開發也不例外,等會我會一一敘述。上一篇提到的是代碼重構思想,這一篇我想談的是同一個插件,不同的設計思想,得到同樣效果。說的有點繞,簡單的說就是殊途同歸的意思。
LazyLoadImg 插件思想
預加載和延遲加載這個說法想必大家都有所了解。WEB中的預加載就是在網頁全部加載之前,對一些主要內容進行加載,以提供給用戶更好的體驗,減少等待的時間。說白了,就是在提前執行相關代碼,提高用戶體驗。延遲加載(lazy load)是(也稱為懶加載),延遲加載機制是為了避免一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正需要數據的時候,才真正執行數據加載操作。當然這兩個思想對於圖片來說,就是提前或是推遲加載圖片。也就這個簡單。
剛剛說到同一插件不同思想的說法。那么我現在說說是啥意思。對於預加載圖片(延遲加載同理),簡單的說就是提前加載圖片。既然是提前,很多人習慣的思想就是通過時間去控制加載圖片,當然這樣是可以的,但是對於不同的場景,都通過時間去控制,那並不一定是最好的方式。就拿本插件為例,如果你用時間去控制預加載的話是很困難的,其實延遲加載也是比較困難的,因為沒有一個時間值比較合適,所以我這里使用滾動條滾動距離(離加載區域的距離)來計算的。
通過滾動距離的一個好處就是易於控制,因為我們在滑動滾動條的時候可以立即知道自己滾動條離加載區域的距離,我們只要控制好這個距離就可以很簡單的完成預加載和延遲加載這兩種情況。既實現了功能,有簡化了邏輯思路和代碼。
雖然這個插件很小,但是我還是用了標准的開發格式寫了,其中也是使用了事件句柄、委托等思想,還有這兩種思想,我之前的博文中也有詳細說明過其優點。這里也不再累述。俗話說麻雀雖小,五臟俱全。這個插件就是這個意思了^_^
插件代碼
本插件屬於簡單插件,所以代碼邏輯也很少,大家隨意看看,都有注釋,還是那句話,注釋是一種良好習慣,希望各位猿們都對自己和別人負責,寫好自己的代碼注釋。如果有不理解的或是有更好見解的,隨時聯系我。下面有我的QQ號。還有公共部分代碼我就不再累述了,前幾篇博文中都有相關代碼,一看便知。
1 /* 2 * instructions :lazyLoadImg 3 * date : 2014-10-27 4 * author : 張文書 5 * Last Modified 2014-10-17 6 * By 張文書 7 */ 8 $(function () { 9 ///說明: 10 /// 預加載圖片和延遲加載圖片 11 var lazyLoadImg = function () { 12 this.defaults = { 13 imgObjList: [],//可見區域需要設置元素的集合 14 lazyHeight: 100, //預加載高度(預判高度>0表示預加載;<0表示延遲加載) 15 hideSrcHost: "",//隱藏img的src地址 16 }; 17 this.options = {}; 18 }; 19 20 lazyLoadImg.prototype = { 21 constructor: lazyLoadImg, 22 init: function (params) { 23 this.options = $.coverObject(this.defaults, params); 24 this._init(); 25 }, 26 _init: function () { 27 this._handleWindowScroll();//初始化加載 28 this._registerWindowScroll(); 29 }, 30 //說明: 31 // 注冊window scroll事件 32 _registerWindowScroll: function () { 33 var handleEvent = $.delegate(this._handleWindowScroll, this); 34 $(window).scroll(handleEvent); 35 }, 36 //說明: 37 // window scroll事件句柄 38 _handleWindowScroll: function () { 39 var lazyHeight = this.options.lazyHeight; 40 var imgObjList = this.options.imgObjList; 41 var hideSrcHost = this.options.hideSrcHost; 42 if (imgObjList.length === 0) { 43 return; 44 } 45 for (var i = 0; i < imgObjList.length; i++) { 46 var objList = imgObjList[i]; 47 $.each(objList, function (j, v) { 48 var id = $(v).attr("id"); 49 if (lazyLoadImg.prototype.boolGetObjList(id, lazyHeight)) { 50 lazyLoadImg.prototype.setProperties(id, hideSrcHost); 51 } 52 }); 53 } 54 }, 55 //說明: 56 // 判斷是否在可視區域情況 1.向上滾動超出可視區域, 2.向下滾動超出可視區域 57 boolGetObjList: function (id, lazyHeight) { 58 var scrollTop = $(window).scrollTop(); 59 var itemTop = $('#' + id).outerHeight(); 60 var itemOffsetTop = $('#' + id).offset().top; 61 var windowHeight = $(window).height(); 62 //不在可視區域 63 if ((scrollTop - lazyHeight > (itemOffsetTop + itemTop)) || ((scrollTop + windowHeight) < itemOffsetTop - lazyHeight)) { 64 return false; 65 } 66 return true; 67 }, 68 //說明: 69 // 當滿足在可見區域時候設置樣式 70 setProperties: function (id, hideSrcHost) { 71 var imgHost = $("#" + id).attr(hideSrcHost); 72 var src = $("#" + id).attr("src"); 73 if (imgHost == src) { 74 return; 75 } 76 $("#" + id).attr("src", imgHost); 77 } 78 }; 79 $.lazyLoadImg = new lazyLoadImg(); 80 });
總結
插件雖小,但是總結還是有必要的。本次插件開發呢,我最大的感觸就是思想很重要。其實當時我開發的時候第一個念頭就是用時間控制,當實現時候才發現,這種思路不是不能用,而是不好用。然后立即掉頭,另尋他法。還好沒有浪費啥太多時間。要知道,開發過程中,當項目很急的時候,一個思想的轉換,是需要勇氣的。所以,當我們在開發時候后,遇到想法上的問題時,我們不妨先放下當前所完成的,不要不舍得那寫好的幾句代碼,說不定你后面想的好方法可以使你事半功倍呢。其實這很自然,因為你后來的想法是基於你當前的想法之上的。
最后呢,如果有需要源碼的或者想共同探討的同仁,隨時聯系我,QQ:296319075 ,注明園友就好,同時也希望大家也能提出寶貴意見,不吝賜教。秉承共同探討、共同進步!如有轉載,請注明出處,謝謝!^_^