首先引入dropload.css
.dropload-up,.dropload-down{ position: relative; height: 0; overflow: hidden; font-size: 12px; /* 开启硬件加速 */ -webkit-transform:translateZ(0); transform:translateZ(0); } .dropload-down{ height: 50px; } .dropload-refresh,.dropload-update,.dropload-load,.dropload-noData{ height: 50px; line-height: 50px; text-align: center; } .dropload-load .loading{ display: inline-block; height: 15px; width: 15px; border-radius: 100%; margin: 6px; border: 2px solid #666; border-bottom-color: transparent; vertical-align: middle; -webkit-animation: rotate 0.75s linear infinite; animation: rotate 0.75s linear infinite; } @-webkit-keyframes rotate { 0% { -webkit-transform: rotate(0deg); } 50% { -webkit-transform: rotate(180deg); } 100% { -webkit-transform: rotate(360deg); } } @keyframes rotate { 0% { transform: rotate(0deg); } 50% { transform: rotate(180deg); } 100% { transform: rotate(360deg); } }
再引入dropload.js
/** * 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){ 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); }; // 初始化 MyDropLoad.prototype.init = function(options){ var me = this; me.opts = $.extend(true, {}, { scrollArea : me.$element, // 滑动区域 domUp : { // 上方DOM domClass : 'dropload-up', domRefresh : '<div class="dropload-refresh">↓下拉刷新</div>', domUpdate : '<div class="dropload-update">↑释放更新</div>', domLoad : '<div class="dropload-load"><span class="loading"></span>加载中...</div>' }, domDown : { // 下方DOM domClass : 'dropload-down', domRefresh : '<div class="dropload-refresh"></div>', domLoad : '<div class="dropload-load"><span class="loading"></span>加载中...</div>', domNoData : '<div class="dropload-noData">暂无更多</div>' }, autoLoad : true, // 自动加载 distance : 50, // 拉动距离 threshold : '', // 提前加载距离 loadUpFn : '', // 上方function loadDownFn : '' // 下方function }, options); // 如果加载下方,事先在下方插入DOM if(me.opts.loadDownFn != ''){ me.$element.append('<div class="'+me.opts.domDown.domClass+'">'+me.opts.domDown.domRefresh+'</div>'); me.$domDown = $('.'+me.opts.domDown.domClass); } // 计算提前加载距离 if(!!me.$domDown && me.opts.threshold === ''){ // 默认滑到加载区2/3处时加载 me._threshold = Math.floor(me.$domDown.height()*1/10); }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('<div class="'+me.opts.domUp.domClass+'"></div>'); 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);
然后关键部分js 自己写的业务
<script> var dropload; var app = new Vue({ el: '#app', data: { page: 1, word: '',//搜索关键字 search: 'favorite', goodslist: [], token: getUrlData()[0], }, methods: { fanhui: function() { var browser = { versions: function() { var a = navigator.userAgent, b = navigator.appVersion; return { trident: a.indexOf("Trident") > -1, presto: a.indexOf("Presto") > -1, webKit: a.indexOf("AppleWebKit") > -1, gecko: a.indexOf("Gecko") > -1 && a.indexOf("KHTML") == -1, mobile: !!a.match(/AppleWebKit.*Mobile.*/), ios: !!a.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), android: a.indexOf("Android") > -1 || a.indexOf("Linux") > -1, iPhone: a.indexOf("iPhone") > -1, iPad: a.indexOf("iPad") > -1, webApp: a.indexOf("Safari") == -1 } }(), language: (navigator.browserLanguage || navigator.language).toLowerCase() }; if (browser.versions.android) { //Android window.Android.webFinish() // window.JsToNative.webFinish(); } else if (browser.versions.ios) { window.webkit.messageHandlers.backClick.postMessage(null) } }, init: function() { var _this = this; dropload = $('.goods').dropload({ //scrollArea很关键,要不然加载更多不起作用 scrollArea: window, loadUpFn: function(me) { console.log(me) //下拉刷新需要调用的函数 console.log("下拉刷新需要调用的函数"); var data = { page: '1', word: _this.word, search: _this.search, order: 'desc' } AXIOS.post('/site/goods_list', data, function(res) { // console.log(res) _this.goodslist = res.data; _this.page++; if (res.data.length >= 8 && me.isLockDown == true) { //解锁 dropload.unlock(); dropload.noData(false); } if (res.data.length < 8) { console.log('加锁') //加锁 dropload.lock(); dropload.noData(); } } ) //重置下拉刷新 me.resetload(); }, loadDownFn: function(me) { //上拉加载更多需要调用的函数 // console.log("上拉加载更多需要调用的函数"); var data = { page: _this.page, //后台传送关键字 word: _this.word, search: _this.search, order: 'desc' } AXIOS.post('http://api.guanjia16.com/site/goods_list', data, function(res) { // console.log(res) _this.goodslist.push.apply(_this.goodslist, res.data) // console.log(_this.goodslist,res.data) _this.page++; //定时器函数,为了看出上拉加载更多效果 setTimeout(function() { // 每次数据加载完,必须重置 me.resetload(); }, 200); if (res.data.length >= 8 && me.isLockDown == true) { //解锁 dropload.unlock(); dropload.noData(false); } // 再往下已经没有数据 if (res.data.length < 8) { console.log('加锁') me.lock(); // 显示无数据 me.noData(); } } ) } }); }, searchBtn: function() { console.log(dropload) var val = this.$refs.input.value; //搜索的关键字 //后台传送关键字 this.word = val; this.goodslist = []; this.page = 1; //dropload定义的全局的 再点击搜索的时候再次调用上拉加载 loadDownFn里面的dropload代表重新执行一次这个上拉加载函数 dropload.opts.loadDownFn(dropload); }, menuBtn: function(e) { console.log(e) this.search = e; // 排序 this.goodslist = []; this.page = 1; dropload.opts.loadDownFn(dropload); } }, mounted() { this.init(); } }) </script>
附图一张: