微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

移动端翻页插件dropload.js支持Zepto和jQuery

dropload.js提供了最基本的上拉翻页,下拉刷新功能。对于由服务端一次返回所有数据的情况基本通用。 但是,需求往往不是服务端一次性返回所有数据,往往还要支持服务端分页搜索,排序,多条件筛选等功能。(比较类似美团美食的界面)

一、解决方

改进1:由于有分页搜索,排序,多条件筛选功能,可能都不需要上拉,进到页面就没有数据。 例如:搜索一个服务端不存在的名字。 所以,添加接口设置setHasData。

rush:js;"> MyDropLoad.prototype.setHasData = function(ishasData) { var me = this; if (ishasData) { me.isData = true; me.$domDown.html(me.opts.domDown.domrefresh); fnRecoverContentHeight(me); } else { me.isData = false; me.$domDown.html(me.opts.domDown.domNoData); fnRecoverContentHeight(me); } };

改进2:由以上问题还引发了一个bug,选择不同的筛选条件,然后上拉加载更多,此时没有反应了。 原因较复杂,举例说明:选择不同的筛选条件,数据量不一样,如果不执行resetload,那么页面的的上拉计算距离就存在问题。 1. 只要发API到服务端,无论返回成功失败,都必须执行resetload,成功时需要在加载完全部新增的数据后resetload。 2. 更改resetload如下,添加调用计算屏幕尺寸的方法

rush:js;"> 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); } else { me.$domDown.html(me.opts.domDown.domNoData); } } }

3. 解决以上两个问题,基本解决了90%的问题,还有一个是setHasData(false)之后的处理。(假设每页的count时20条) bug: 在筛序条件1:返回20条数据,上拉加载更多返回10条数据,此时设置setHasData(false)。选择筛选条件2,返回20条数据,上拉加载,你会惊奇的发现拉不动了。 why: setHasData(false)之后状态还停留在没有更多数据的状态。此时应该锁定了上拉加载,更改筛选条件后,没有解除锁定,所以不能上拉加载了。 解决方法:每次更改搜索条件,筛选条件,排序等时,都需要设置setHasData(true)。

二、调用方法

整体页面逻辑较复杂。这里在整体解释一遍。 1. 选择要上拉加载的DIV,添加调用方法注意事项: (1)记得保存返回对象。 (2)LoadDownFn时上拉加载后的回调,这里自己要处理的逻辑。我这里时翻页发API,API参数中offset加20,然后发API。 (3)无论API返回失败成功,都必须resetload。 这里强调: fetchData函数调用发API,失败或者成功都必须self.morefund.resetload()。 并且失败时直接调用self.morefund.resetload()即可。成功时要在新的数据返回后,要先用JS动态加载HTML,加载完成后在执行self.morefund.resetload()。

rush:js;"> self.morefund = $('#table-fundlist').dropload({ scrollArea: window,domDown: { domClass: 'dropload-down',domrefresh: '
上拉加载更多
',domload: '
',domNoData: '' },loadDownFn: function() { self.apiParams.offset += 20; self.fetchData(true); } });

2. setHasData详解 (1)什么时候需要设置true。 当非翻页API触发之前。即选择新的筛选条件,选择新的搜索字段,选择新的排序字段。这个时候必须setHasData(true)。 refund.setHasData(true); (2)什么时候设置false。 服务端返回数据后,比较服务端返回的条目数与API发送的条目数是否一致,不一致设置setHasData(false)。

rush:js;"> if (data.length < this.apiParams.count){ this.morefund.setHasData(false); this.morefund.lock(); }

3. lock与unlock详解 (1)什么时候设置lock。 服务端返回数据后,比较服务端返回的条目数与API发送的条目数是否一致,不一致设置lock()。 当前页面状态不需要上拉加载时需要设置lock()。例如:在搜索框输入的状态。 (2)什么时候设置unlock。 只有一个地方需要调用。发送API之前设置unlock。

rush:js;"> if (self.morefund) { self.morefund.unlock(); }

三、JS和CSS源代码

js:

rush:js;"> (function($) { 'use strict'; var win = window; var doc = document; var $win = $(win); var $doc = $(doc); $.fn.dropload = function(options) { return new MyDropLoad(this,options); }; var MyDropLoad = function(element,options) { var me = this; me.$element = $(element); me.upInsertDOM = false; me.loading = false; me.isLockUp = false; me.isLockDown = false; me.isData = true; me._scrollTop = 0; me.init(options); }; MyDropLoad.prototype.init = function(options) { var me = this; me.opts = $.extend({},{ scrollArea: me.$element,domUp: { domClass: 'dropload-up',domrefresh: '
下拉刷新
',domUpdate: '
释放更新
',domload: '
' },domDown: { domClass: 'dropload-down',domrefresh: '
上拉加载更多
',domload: '
',domNoData: '' //domNoData : '
暂无数据
' },distance: 50,// 拉动距离 threshold: '',// 提前加载距离 loadUpFn: '',// 上方function loadDownFn: '' // 下方function },options);

if (me.opts.loadDownFn != '') {
me.$element.append('<div class="' + me.opts.domDown.domClass + '">' + me.opts.domDown.domrefresh + '

');
me.$domDown = $('.' + me.opts.domDown.domClass);
}

if (me.opts.scrollArea == win) {
me.$scrollArea = $win;
me._scrollContentHeight = $doc.height();
me._scrollWindowHeight = doc.documentElement.clientHeight;
} else {
me.$scrollArea = me.opts.scrollArea;
me._scrollContentHeight = me.$element[0].scrollHeight;
me._scrollWindowHeight = me.$element.height();
}

$win.on('resize',function() {
if (me.opts.scrollArea == 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();
fnRecoverContentHeight(me)
if (me.opts.threshold === '') {
me._threshold = Math.floor(me.$domDown.height() * 1 / 3);
} else {
me._threshold = me.opts.threshold;
}
if (me.opts.loadDownFn != '' && !me.loading && !me.isLockDown && me._threshold != 0 && (me._scrollContentHeight - me._threshold) <= (me._scrollWindowHeight + me._scrollTop)) {
fnLoadDown();
}
});

function fnLoadDown() {
me.direction = 'up';
me.$domDown.html(me.opts.domDown.domLoad);
me.loading = true;
me.opts.loadDownFn(me);
}
};

function fnTouches(e) {
if (!e.touches) {
e.touches = e.originalEvent.touches;
}
}

function fnTouchstart(e,me) {
me._startY = e.touches[0].pageY;
me.touchScrollTop = me.$scrollArea.scrollTop();
}

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);
if (!me.upInsertDOM) {
me.$element.prepend('<div class="' + me.opts.domUp.domClass + '">

');
me.upInsertDOM = true;
}
fnTransition(me.$domUp,0);
if (_absMoveY <= me.opts.distance) {
me._offsetY = _absMoveY;
me.$domUp.html(me.opts.domUp.domRefresh);
} 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);
} 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 transitionend',function() {
me.upInsertDOM = false;
$(this).remove();
});
}
me._moveY = 0;
}
}

// 重新获取文档高度
function fnRecoverContentHeight(me) {
if (me.opts.scrollArea == win) {
me._scrollContentHeight = $doc.height();
} else {
me._scrollContentHeight = me.$element[0].scrollHeight;
}
}

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;
}
};

MyDropLoad.prototype.unlock = function() {
var me = this;
me.isLockUp = false;
me.isLockDown = false;
};

MyDropLoad.prototype.setHasData = function(ishasData) {
var me = this;
if (ishasData) {
me.isData = true;
me.$domDown.html(me.opts.domDown.domrefresh);
fnRecoverContentHeight(me);
} else {
me.isData = false;
me.$domDown.html(me.opts.domDown.domNoData);
fnRecoverContentHeight(me);
}
};

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);
} else {
me.$domDown.html(me.opts.domDown.domNoData);
}
}
};

function fnTransition(dom,num) {
dom.css({
'-webkit-transition': 'all ' + num + 'ms','transition': 'all ' + num + 'ms'
});
}
})(window.Zepto || window.jQuery);

CSS:

rush:css;"> .dropload-up,.dropload-down { background-color: #F0EFF5; position: relative; height: 0; overflow: hidden; }

.dropload-down {
height: 50px;
border-top: 1px solid #e5e5e5;
}

.dropload-refresh .drop-up-icon,.dropload-refresh .drop-down-icon,.dropload-update .drop-up-icon,.dropload-update .drop-down-icon {
vertical-align: text-bottom;
margin-right: 3px;
height: 16px;
width: 12px;
}

.dropload-load .loading-icon {
vertical-align: middle;
height: 20px;
width: 20px;
}

.dropload-refresh span,.dropload-update span {
vertical-align: middle;
line-height: 18px;
font-size: 16px;
color: #585858;
}

.dropload-noData {
border-bottom: 1px solid #e5e5e5;
background-color: #FFFFFF;
}

.dropload-noData span {
line-height: 18px;
font-size: 14px;
color: #999999;
}

.dropload-refresh,.dropload-update,.dropload-load,.dropload-noData {
position: absolute;
width: 100%;
height: 50px;
bottom: 0;
line-height: 50px;
text-align: center;
}

.dropload-down .dropload-refresh,.dropload-down .dropload-update,.dropload-down .dropload-load {
top: 0;
bottom: auto;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

原文地址:https://www.jb51.cc/jquery/47069.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐