We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
上篇我在文章中分析了如何去实现瀑布流的布局,以及怎么使用模版去实现数据的插入到html之中。这一篇,主要讲一下三部分的实现,1.数据mock、2.下拉加载、3.上拉刷新。本次demo的地址在此,喜欢的可以给一个Star
首先,我们来分析一下数据的mock部分。由于想要实现与具备后台一样的效果,我们必须使用node去实现一个mock的后台,将数据放在json中,然后使用fs模块读取里面的内容,然后根据url进行数据的检索。
一般来说,下拉加载的数据都是具备分页特性的。主要可分为data(数据段)、page(当前页码)、next(告知前端接下来是否还有数据内容)。
之后,我们通过express框架对整个后端的数据进行一下模拟。我的demo目录下,有已经构造好的json文件,一共是两份,一份是更新前的数据,一份是更新后的数据。具体实现的代码:
const Express = require('express'); const app = new Express(); const path = require('path'); const fs = require('fs'); //data part app.get('/:id', function(req, res){ const page = req.params.id; res.setHeader("Access-Control-Allow-Origin", "*"); // console.log(page); fs.readFile(path.resolve(__dirname, 'mock.json'), function(err, data){ if(err){ throw err; } const static = JSON.parse(data).data; const arr = Array.from(static); const len = arr.length; const next = page - 0 + 1 <= len ? true : false; for(let value of arr){ if(value.page == page){ res.json({data: value.data, next: next}); } } }); }); app.get('/update/:id', function(req, res){ const page = req.params.id; res.setHeader('Access-Control-Allow-Origin', '*'); fs.readFile(path.resolve(__dirname, 'update.json'), function(err, data){ if(err){ throw err; } const static = JSON.parse(data).data; const arr = Array.from(static); const next = page - 0 + 1 <= arr.length ? true : false; let result = []; for(let value of arr){ if(value.page <= page){ result = result.concat(value.data); } } res.json({data: result, next: next}); }); }); app.listen(3000);
这部分主要是读取json文件中的数据,然后将它一个固定的json格式返回给前端。源码地址。
之后,我么开始来实现h5的下拉加载部分。
如果是我自己写的话,我会将下拉加载分成三个步骤进行实现:
但是,这样子的实现方式往往不是最佳的方式。最佳的方式,是类似与iscroll和better-scroll插件的方式。原理:在最外层设置一个wrapper(包),将包的大小绝对定位和内容隐藏,然后给内部的内容添加transform的动画属性,使得它可以进行上下的滚动。这样的好处是,可以实现回弹的效果。
原理图:
better-scroll在iscroll上面做了一些修缮,尤其是在触摸滚动方面吧。所以可以使用better-scroll来实现下拉加载和上拉刷新。
第一步:固定外层包的大小,使用绝对定位的方式。然后在内容的上下都添加loading图。示例:
<div id="wrapper"> <div> <div class="pull-refresh" id="pull-refresh"> <div class="arrow" id="arrow"> <img src="https://raw.githubusercontent.com/AlloyTeam/AlloyTouch/master/refresh/pull_refresh/asset/arrow.png" alt="arrow"><br> </div> </div> <div id="toploading"> <img src="./images/200.gif" alt="loading"> </div> <ul class="wrapper"> </ul> <div class="bottom" id="bottom"> <span class="line"></span> <span class="tip">我是底线</span> <span class="line"></span> </div> <div class="loading" id="loading"> <img src="./images/200.gif" alt="loading"> </div> </div> </div>
之后就是一些样式的设置。
第二步:初始化scroll的对象,可以通过BScroll去进行构造。然后在每次载入内容的时候都需要去刷新一下scroll,保证它对内部内容的识别是正确的。否则,你可能只能滚动一部分。(由于是ajax载入数据的,所以在刷新的时候需要一定的延时,才能保证内容的正确)
//init scroll part _initScroll: function(){ const _self = this; const wrapper = document.getElementById('wrapper') const options = { probeType: 1, click: true, scrollbar: false, bounduceTime: 2000 }; _self.scroll = new BScroll(wrapper, options); }, //ajax part fetch: function(url){ return new Promise((resolve, reject) => { $.ajax({ url: url, type: 'GET', dataType: 'json', data: {}, success: function(data){ resolve(data); }, error: function(){ reject('request timeout'); } }); }); }, load: function(fn){ const _self = this; const url = _self.config.base_url + _self.data.page; _self.operations.bShow(); _self.scroll.refresh(); return _self.fetch(url).then(data => { setTimeout(() => { _self.operations.bHide(); _self.data.next = data.next; if(!data.next){ _self.bottomLine(); } _self.data.page++; fn.call(_self, data.data); _self.data.status = 'ready'; }, 500); setTimeout(() => { _self.scroll.refresh(); }, 600); }, err => { console.log(err); }).catch(e => console.log(e)); }, update: function(fn){ const _self = this; const url = _self.config.base_url + 'update/' + (_self.data.page - 1); _self.operations.tShow(); _self.operations.aHide(); return _self.fetch(url).then(data => { setTimeout(() => { _self.operations.tHide(); _self.operations.aShow(); _self.data.next = data.next; fn.call(_self, data.data); }, 500); setTimeout(() => { _self.scroll.refresh(); _self.data.status = 'ready'; }, 600); }, er => { console.log(err); }).catch(e => console.log(e)); },
这部分主要分为三个函数fetch、load、update。它们的作用分别是fetch主要是一个发起ajax请求的函数,以promise的形式,将内容返回回来,便于后面的数据操作。load主要作用就是获取下拉加载的数据,将它加载到html中去,update是上拉刷新后的数据,将它重新替换html中列表部分的内容。这里有一个status去控制加载的状态,防止重复发送ajax请求。
第三步:就是给scroll去添加事件。主要是两个事件touchEnd和scroll事件。这里的scroll事件是当滚动列表时发生整体的滚动时才会触发的。因为我们的html结构中,wrapper内的内容除了ul列表之外头部和尾部都还具备loading的标签。
bind: function(){ const _self = this; _self.scroll.on('touchEnd', function(position){ if(position.y < _self.scroll.maxScrollY - 20){ _self.more(); }else if(position.y > 80){ _self.update(_self.initHtml); } }); _self.scroll.on('scroll', function(position){ if(position.y > 80){ _self.operations.up(); }else{ _self.operations.down(); } }); },
然后通过后端传过来的next可以帮助我们去判断是否还有后续内容,position.y对应的就是transform动画滚动时的值。然后,去判断是否到达底部是,我们还需要的是scroll中maxScrollY这个值。其中的20只是一个阈值。
这样其实一个下拉刷新和上拉加载的过程就算是完成了。后续还可以改进的地方有是图片的懒加载和js模版引擎的使用。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
上篇我在文章中分析了如何去实现瀑布流的布局,以及怎么使用模版去实现数据的插入到html之中。这一篇,主要讲一下三部分的实现,1.数据mock、2.下拉加载、3.上拉刷新。本次demo的地址在此,喜欢的可以给一个Star
正文
首先,我们来分析一下数据的mock部分。由于想要实现与具备后台一样的效果,我们必须使用node去实现一个mock的后台,将数据放在json中,然后使用fs模块读取里面的内容,然后根据url进行数据的检索。
一般来说,下拉加载的数据都是具备分页特性的。主要可分为data(数据段)、page(当前页码)、next(告知前端接下来是否还有数据内容)。
之后,我们通过express框架对整个后端的数据进行一下模拟。我的demo目录下,有已经构造好的json文件,一共是两份,一份是更新前的数据,一份是更新后的数据。具体实现的代码:
这部分主要是读取json文件中的数据,然后将它一个固定的json格式返回给前端。源码地址。
之后,我么开始来实现h5的下拉加载部分。
如果是我自己写的话,我会将下拉加载分成三个步骤进行实现:
但是,这样子的实现方式往往不是最佳的方式。最佳的方式,是类似与iscroll和better-scroll插件的方式。原理:在最外层设置一个wrapper(包),将包的大小绝对定位和内容隐藏,然后给内部的内容添加transform的动画属性,使得它可以进行上下的滚动。这样的好处是,可以实现回弹的效果。
原理图:
better-scroll在iscroll上面做了一些修缮,尤其是在触摸滚动方面吧。所以可以使用better-scroll来实现下拉加载和上拉刷新。
第一步:固定外层包的大小,使用绝对定位的方式。然后在内容的上下都添加loading图。示例:
之后就是一些样式的设置。
第二步:初始化scroll的对象,可以通过BScroll去进行构造。然后在每次载入内容的时候都需要去刷新一下scroll,保证它对内部内容的识别是正确的。否则,你可能只能滚动一部分。(由于是ajax载入数据的,所以在刷新的时候需要一定的延时,才能保证内容的正确)
这部分主要分为三个函数fetch、load、update。它们的作用分别是fetch主要是一个发起ajax请求的函数,以promise的形式,将内容返回回来,便于后面的数据操作。load主要作用就是获取下拉加载的数据,将它加载到html中去,update是上拉刷新后的数据,将它重新替换html中列表部分的内容。这里有一个status去控制加载的状态,防止重复发送ajax请求。
第三步:就是给scroll去添加事件。主要是两个事件touchEnd和scroll事件。这里的scroll事件是当滚动列表时发生整体的滚动时才会触发的。因为我们的html结构中,wrapper内的内容除了ul列表之外头部和尾部都还具备loading的标签。
然后通过后端传过来的next可以帮助我们去判断是否还有后续内容,position.y对应的就是transform动画滚动时的值。然后,去判断是否到达底部是,我们还需要的是scroll中maxScrollY这个值。其中的20只是一个阈值。
总结
这样其实一个下拉刷新和上拉加载的过程就算是完成了。后续还可以改进的地方有是图片的懒加载和js模版引擎的使用。
The text was updated successfully, but these errors were encountered: