/**
* 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);