使用mescroll实现上拉加载与下拉刷新
现在上拉加载与下拉刷新几乎已经是移动端必备功能之一了,自己实现一个太麻烦,但是好用的插件又非常少。之前看到网上很多人都在用iScroll,于是也尝试用它做了几个DEMO,但或多或少都有一些问题,比如这个插件缺少暂停/恢复滚动的功能,数据不满一页时上拉有问题,等等。官方也没有提供相应的例子,加上配置项非常多,作者也不维护了,最后只好放弃研究。后来偶然发现了mescroll这个框架,并且官网提供的例子非常丰富,比较符合国内移动端的开发需求,于是打算尝试一下。
虽然官网的例子down下来是可以运行的,但并非真实数据,在切换到真实数据源后,也出现了各种各样的问题,这里记录一下遇到的问题和解决方案。首先是HTML结构:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>mescroll下拉刷新与上拉加载更多</title> <!--mescroll.min.css为mescroll的样式文件,必须引用--> <link rel="stylesheet" href="css/mescroll.min.css"> <!--scroll.css为自定义样式,非必须--> <link rel="stylesheet" href="scroll.css"> <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script> <!--mescroll.min.js为mescroll的脚本文件,必须引用--> <script src="js/mescroll.min.js"></script> <!--scroll.js为自定义脚本,非必须--> <script src="scroll.js"></script> </head> <body> <header>Header</header> <!--mescroll这个样式是框架的硬性要求,不能删,但可以在样式表中覆盖--> <div id="is-0" class="mescroll"> <ul class="dataList" id="dataList"></ul> </div> <footer>Footer</footer> </body> </html>
结构比较简单,一个header一个footer外加中间一个滚动容器。接下来是scroll.css里的样式编写:
/* 头尾的样式,采用fixed布局,不重要 */ header, footer { height: 50px; text-align: center; line-height: 50px; text-shadow: black 0.1em 0.1em 0.2em; color: #ffffff; left: 0; width: 100%; position: fixed; background: #4bbaf2; background: -moz-linear-gradient(top, #4bbaf2 0%, #4bbaf2 52%, #2d80e5 100%); background: -webkit-linear-gradient(top, #4bbaf2 0%, #4bbaf2 52%, #2d80e5 100%); background: linear-gradient(to bottom, #4bbaf2 0%, #4bbaf2 52%, #2d80e5 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4bbaf2', endColorstr='#2d80e5', GradientType=0); } header { top: 0; } footer { bottom: 0; } /* end */ /*********** 滚动容器的样式start (重点关注这一部分) ***********/ .mescroll { position: fixed; top: 50px; bottom: 50px; left: 0; height: auto; /*mescroll.min.css中使用了height:100%,与现有布局冲突,所以这里通过height:auto覆盖掉*/ background: #f6f6f6; } /*滚动列表的样式*/ .mescroll .dataList { min-height: 100%; /*通过设置最小高度,可以把上拉加载的提示撑到底部,不然没有数据或数据较少时会在页面显示出来,不美观*/ } /*数据为空时显示的图标及文案,垂直居中*/ .mescroll .dataList .mescroll-empty { padding-top: 0; position: absolute; top: 50%; transform: translate(0, -50%); } /*********** 滚动容器的样式end ***********/ /* li及里面内容的样式,按照自己需求定制即可,不重要 */ .mescroll .dataList li { padding: 10px; overflow: hidden; border-bottom: 1px solid #ccc; word-break: break-all; } .mescroll .dataList li h3 { font-size: 14px; } .mescroll .dataList li p { font-size: 12px; margin-top: 5px; color: #666; }
最终得到的效果页面如下:
分页测试数据的准备
页面结构已经搭好了,现在还差能够测试的数据。测试数据最好不依赖数据库和复杂的服务器环境,折腾起来太麻烦。这里推荐一个基于node.js的第三方工具 json-server ,可以模拟分页数据。安装成功后,在任一目录下新建一个db.json文件,并写入一些测试数据,
{ "posts": [ { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }, { "userId": 1, "id": 2, "title": "qui est esse", "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" }, { "userId": 1, "id": 3, "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" }] }
然后在当前目录打开命令行,执行 json-server db.json --watch
然后会得到一个链接, http://localhost:3000/posts
,访问这个链接就能得到测试数据了。现在来试试分页,按照文档中的配置在url中输入http://localhost:3000/posts?_limit=10&_page=1
发现已经可以取到分页数据了。最后就是初始化mescroll:
var mescroll = new MeScroll("is-0", { up: { callback: upCallback, //上拉加载的回调 isBounce: false, //如果您的项目是在iOS的微信,QQ,Safari等浏览器访问的,建议配置此项 auto: true, htmlNodata: '<span style="font-size:12px">没有更多数据了</span>', toTop: { src: '这里放返回顶部的图片路径', offset: 80 }, empty: {//数据为空 warpId:'dataList', //对应ul元素的id icon: '这里放数据为空时展示的图片路径', tip: "暂无相关数据~", btntext: "", btnClick: null, supportTap: false } } });
由于下拉刷新mescroll在内部已经配置好了,所以没有特殊需求就不用再次配置,最后看看upCallback回调,这个方法处理上拉加载:
function upCallback(page) { page.size = 10; //每页显示的数据条数,mescroll内置默认为10 var data = {_limit: page.size, _page: page.num}; //page.num由mescroll内部控制,从1开始,不用做特殊处理,如果想从0开始 $.get('http://localhost:3000/comments', data, function (data) { var container = $('#is-0'); var content = ''; var len = data.length; //保存此次请求获取到的数据个数,endBySize要用到这个变量 $.each(data, function (index, item) { content += `<li><h3>${item.title}</h3><p>${item.body}</p></li>`; }); var listBox = container.find('ul').eq(0); //如果请求为第一页,清空列表后再往里填充数据,是针对下拉刷新的处理 if (page.num === 1) listBox.empty(); listBox.append(content); mescroll.endBySize(len, total); //total为数据总量,由接口返回。测试数据中没有提供是因为接口不支持。 }); }
最后的效果如下: