標籤:自訂 element data length eid window logs 代碼 lan
先上代碼
enum LazyMode { once, // 執行一次模式 every //永久執行模式 } class LazyItem { constructor( public element: JQuery, public callback: Function, public mode: LazyMode = LazyMode.once, public diff: number = 0 ) { } private _lastHeight: number; // 上次執行的高度 /** * 重新重新整理 */ public refresh() { this._lastHeight = undefined; } /** * 判斷能否執行 * @param height * @param bottom */ public canRun(height: number, bottom: number): boolean { if (this.mode == LazyMode.once && this._lastHeight) { return false } let top = this.element.offset().top; return top + this.diff >= height && top < bottom; } public run(height: number, bottom: number): boolean { if (this.mode == LazyMode.once && this._lastHeight) { return false; } let top = this.element.offset().top; if (top + this.diff < height || top >= bottom) { return false; } this.callback.call(this, this.element); this._lastHeight = height + this.diff; return true; } } class Lazy { constructor( public element: JQuery, options?: LazyOptions ) { this.options = $.extend({}, new LazyDefaultOptions(), options); let $window = $(window); let instance = this; this._init(); $window.scroll(function() { instance.scrollInvote(); }); // 首次執行 this.scrollInvote(); } public options: LazyOptions; private _data: Array<LazyItem>; /** * 頁面滾動觸發更新 */ public scrollInvote() { let $window = $(window); let height = $window.scrollTop(); let bottom = $window.height() + height; this.run(height, bottom); } public run(height: number, bottom: number) { if (!this._data) { return; } for(let i = this._data.length - 1; i >= 0; i --) { let item = this._data[i]; if (item.run(height, bottom) && item.mode == LazyMode.once) { this._data.splice(i, 1); } } } // 暫時只做一次 private _init() { if (typeof this.options.callback != ‘function‘) { this.options.callback = Lazy.getMethod(this.options.callback); } this._data = []; let instance = this; this.element.each(function(i, ele) { let item = new LazyItem($(ele), instance.options.callback, instance.options.mode, instance.options.diff); instance._data.push(item); }); } /** * 全域方法集合 */ public static methods: {[name: string]: Function} = {}; /** * 添加方法 * @param name * @param callback */ public static addMethod(name: string, callback: Function) { this.methods[name] = callback; } /** * 擷取方法 * @param name */ public static getMethod(name: string): Function { return this.methods[name]; }}/** * 載入圖片,如需載入動畫控制請自訂 */Lazy.addMethod(‘img‘, function(imgEle: JQuery) { var img = imgEle.attr(‘data-original‘); $("<img />") .bind("load", function() { imgEle.attr(‘src‘, img); }).attr(‘src‘, img);});/** * 載入模板,需要引用 template 函數 */Lazy.addMethod(‘tpl‘, function(tplEle: JQuery) { var url = tplEle.attr(‘data-url‘); var templateId = tplEle.attr(‘data-tpl‘); $.getJSON(url, function(data) { if (data.code != 0) { return; } if (typeof data.data != ‘string‘) { data.data = template(templateId, data.data); } tplEle.html(data.data); });});interface LazyOptions { [setting: string]: any, data?: {[tag: string]: string | Object} | Array<Object> | Array<Lazy>, // 忘記了最初要做什麼了,等想起來再加上對應功能 tag?: string| JQuery, callback?: string | Function, // 回調 mode?: LazyMode, //執行模式 diff?: number, //距離可視化地區的距離 } class LazyDefaultOptions implements LazyOptions { mode: LazyMode = LazyMode.once; diff: number = 0 } ;(function($: any) { $.fn.lazyload = function(options ?: LazyOptions) { return new Lazy(this, options); };})(jQuery);
本外掛程式使用 typescript 編寫, js 請查看 GITHUB
本外掛程式內建兩個方法:
1.簡單的圖片載入。可以參考增加載入動畫 給 img 的 src 設定一張 載入動態圖片
<img class="lazy" data-original="1.jpg"/>
$("img.lazy").lazyload({ callback: function($this) { var img = $this.attr(‘data-original‘); if (!img) { return; } $("<img />").bind("load", function() { $this.attr(‘src‘, img); }).attr(‘src‘, img); }});
2.局部載入。依賴 template 函數(參考 art-template)
<div class="templateLazy lazy-loading" data-url="1" data-tpl="temp_tpl"></div>
主要有兩個參數 :
data-url 請求網址
data-tpl 模板元素id
(lazy-loading 為載入動畫)
<script id="temp_tpl" type="text/template"> <div>{{ id }}</div></script>
$(".templateLazy").lazyload({ callback: function($this) { var url = $this.attr(‘data-url‘); var templateId = $this.attr(‘data-tpl‘); $.getJSON(url, function(data) { if (data.code != 0) { return; } if (typeof data.data != ‘string‘) { data.data = template(templateId, data.data); } $this.removeClass(‘lazy-loading‘); $this.html(data.data); }); }});
請注意,本外掛程式依賴 jquery
jquery外掛程式系列之消極式載入