/** * dropload * 西門(http://ons.me/526.html) * 0.9.0(160215) */ ; (function ($) { 'use strict'; var win = window; var doc = document; var $win = $(win); var $doc = $(doc); $.fn.dropload = function (options) { console.log('this', this); return new MyDropLoad(this, options); }; var MyDropLoad = function (element, options) { var me = this; me.$element = element; // 上方是否插入DOM me.upInsertDOM = false; // loading狀態 me.loading = false; // 是否鎖定 me.isLockUp = false; me.isLockDown = false; // 是否有數據 me.isData = true; me._scrollTop = 0; me._threshold = 0; me.init(options); console.log('element', element); }; // 初始化 MyDropLoad.prototype.init = function (options) { var me = this; me.opts = $.extend(true, {}, { scrollArea: me.$element, // 滑動區域 domUp: { // 上方DOM domClass: 'dropload-up', domRefresh: '
↓下拉刷新
', domUpdate: '
↑釋放更新
', domLoad: '
加載中...
' }, domDown: { // 下方DOM domClass: 'dropload-down', domRefresh: '
↑上拉加載更多
', domLoad: '
加載中...
', domNoData: '
沒有更多了
' }, autoLoad: true, // 自動加載 distance: 50, // 拉動距離 threshold: '', // 提前加載距離 loadUpFn: '', // 上方function loadDownFn: '' // 下方function }, options); // 如果加載下方,事先在下方插入DOM if (me.opts.loadDownFn != '') { me.$element.append('
' + me.opts.domDown.domRefresh + '
'); me.$domDown = $('.' + me.opts.domDown.domClass); } // 計算提前加載距離 if (!!me.$domDown && me.opts.threshold === '') { // 默認滑到加載區2/3處時加載 me._threshold = Math.floor(me.$domDown.height() * 1 / 3); } else { me._threshold = me.opts.threshold; } // 判斷滾動區域 if (me.opts.scrollArea == win) { me.$scrollArea = $win; // 獲取文檔高度 me._scrollContentHeight = $doc.height(); // 獲取win顯示區高度 —— 這裏有坑 me._scrollWindowHeight = doc.documentElement.clientHeight; } else { me.$scrollArea = me.opts.scrollArea; me._scrollContentHeight = me.$element[0].scrollHeight; me._scrollWindowHeight = me.$element.height(); } fnAutoLoad(me); // 窗口調整 $win.on('resize', function () { if (me.opts.scrollArea == win) { // 重新獲取win顯示區高度 me._scrollWindowHeight = win.innerHeight; } else { me._scrollWindowHeight = me.$element.height(); } }); // 綁定觸摸 me.$element.on('touchstart', function (e) { if (!me.loading) { fnTouches(e); fnTouchstart(e, me); } }); me.$element.on('touchmove', function (e) { if (!me.loading) { fnTouches(e, me); fnTouchmove(e, me); } }); me.$element.on('touchend', function () { if (!me.loading) { fnTouchend(me); } }); // 加載下方 me.$scrollArea.on('scroll', function () { me._scrollTop = me.$scrollArea.scrollTop(); // 滾動頁面觸發加載數據 if (me.opts.loadDownFn != '' && !me.loading && !me.isLockDown && (me._scrollContentHeight - me._threshold) <= (me._scrollWindowHeight + me._scrollTop)) { loadDown(me); } }); }; // touches function fnTouches (e) { if (!e.touches) { e.touches = e.originalEvent.touches; } } // touchstart function fnTouchstart (e, me) { me._startY = e.touches[0].pageY; // 記住觸摸時的scrolltop值 me.touchScrollTop = me.$scrollArea.scrollTop(); } // touchmove function fnTouchmove (e, me) { me._curY = e.touches[0].pageY; me._moveY = me._curY - me._startY; if (me._moveY > 0) { me.direction = 'down'; } else if (me._moveY < 0) { me.direction = 'up'; } var _absMoveY = Math.abs(me._moveY); // 加載上方 if (me.opts.loadUpFn != '' && me.touchScrollTop <= 0 && me.direction == 'down' && !me.isLockUp) { e.preventDefault(); me.$domUp = $('.' + me.opts.domUp.domClass); // 如果加載區沒有DOM if (!me.upInsertDOM) { me.$element.prepend('
'); me.upInsertDOM = true; } fnTransition(me.$domUp, 0); // 下拉 if (_absMoveY <= me.opts.distance) { me._offsetY = _absMoveY; // todo:move時會不斷清空、增加dom,有可能影響性能,下同 me.$domUp.html(me.opts.domUp.domRefresh); // 指定距離 < 下拉距離 < 指定距離*2 } else if (_absMoveY > me.opts.distance && _absMoveY <= me.opts.distance * 2) { me._offsetY = me.opts.distance + (_absMoveY - me.opts.distance) * 0.5; me.$domUp.html(me.opts.domUp.domUpdate); // 下拉距離 > 指定距離*2 } else { me._offsetY = me.opts.distance + me.opts.distance * 0.5 + (_absMoveY - me.opts.distance * 2) * 0.2; } me.$domUp.css({ 'height': me._offsetY }); } } // touchend function fnTouchend (me) { var _absMoveY = Math.abs(me._moveY); if (me.opts.loadUpFn != '' && me.touchScrollTop <= 0 && me.direction == 'down' && !me.isLockUp) { fnTransition(me.$domUp, 300); if (_absMoveY > me.opts.distance) { me.$domUp.css({ 'height': me.$domUp.children().height() }); me.$domUp.html(me.opts.domUp.domLoad); me.loading = true; me.opts.loadUpFn(me); } else { me.$domUp.css({ 'height': '0' }).on('webkitTransitionEnd mozTransitionEnd transitionend', function () { me.upInsertDOM = false; $(this).remove(); }); } me._moveY = 0; } } // 如果文檔高度不大於窗口高度,數據較少,自動加載下方數據 function fnAutoLoad (me) { if (me.opts.autoLoad) { if ((me._scrollContentHeight - me._threshold) <= me._scrollWindowHeight) { loadDown(me); } } } // 重新獲取文檔高度 function fnRecoverContentHeight (me) { if (me.opts.scrollArea == win) { me._scrollContentHeight = $doc.height(); } else { me._scrollContentHeight = me.$element[0].scrollHeight; } } // 加載下方 function loadDown (me) { me.direction = 'up'; me.$domDown.html(me.opts.domDown.domLoad); me.loading = true; me.opts.loadDownFn(me); } // 鎖定 MyDropLoad.prototype.lock = function (direction) { var me = this; // 如果不指定方向 if (direction === undefined) { // 如果操作方向向上 if (me.direction == 'up') { me.isLockDown = true; // 如果操作方向向下 } else if (me.direction == 'down') { me.isLockUp = true; } else { me.isLockUp = true; me.isLockDown = true; } // 如果指定鎖上方 } else if (direction == 'up') { me.isLockUp = true; // 如果指定鎖下方 } else if (direction == 'down') { me.isLockDown = true; // 為了解決DEMO5中tab效果bug,因為滑動到下面,再滑上去點tab,direction=down,所以有bug me.direction = 'up'; } }; // 解鎖 MyDropLoad.prototype.unlock = function () { var me = this; // 簡單粗暴解鎖 me.isLockUp = false; me.isLockDown = false; // 為了解決DEMO5中tab效果bug,因為滑動到下面,再滑上去點tab,direction=down,所以有bug me.direction = 'up'; }; // 無數據 MyDropLoad.prototype.noData = function (flag) { var me = this; if (flag === undefined || flag == true) { me.isData = false; } else if (flag == false) { me.isData = true; } }; // 重置 MyDropLoad.prototype.resetload = function () { var me = this; if (me.direction == 'down' && me.upInsertDOM) { me.$domUp.css({ 'height': '0' }).on('webkitTransitionEnd mozTransitionEnd transitionend', function () { me.loading = false; me.upInsertDOM = false; $(this).remove(); fnRecoverContentHeight(me); }); } else if (me.direction == 'up') { me.loading = false; // 如果有數據 if (me.isData) { // 加載區修改樣式 me.$domDown.html(me.opts.domDown.domRefresh); fnRecoverContentHeight(me); fnAutoLoad(me); } else { // 如果沒數據 me.$domDown.html(me.opts.domDown.domNoData); } } }; // css過渡 function fnTransition (dom, num) { dom.css({ '-webkit-transition': 'all ' + num + 'ms', 'transition': 'all ' + num + 'ms' }); } })(window.Zepto || window.jQuery);