补充一些文档里没有的。
官方案例里,就是pullrefresh_main.html和pullrefresh_sub.html这两个文件。
在pullrefresh_main.html中:
- if(mui.os.ios){
- contentWebview.evalJS("mui('#pullrefresh').pullRefresh().scrollTo(0,0,100)");
- }else{
- contentWebview.evalJS('mui.scrollTo(0, 100)');
- }
其中mui('#pullrefresh')获得了子页面中id为pullrefresh的div的对象,这段代码的目的是让让滚动条在顶部。如官方文档所言,Android是用Webview实现,iOS是用H5(div)实现。下面这个代码是针对Android使用HTML5+实现的。在iOS中,用div模拟scroll,因此scrollTo方法属于pullRefresh这个方法返回的js对象。而对于Android而言,使用的是H5+扩展,scrollTo直接就是Webkit方法。
在pushfresh_sub.html中调用了pullRefresh().pullupLoading()的,目的是为了初始化(首次加载)表格:
- if (mui.os.plus) {
- mui.plusReady(function() {
- setTimeout(function() {
- mui('#pullrefresh').pullRefresh().pullupLoading();
- }, 1000);
- });
- } else {
- mui.ready(function() {
- mui('#pullrefresh').pullRefresh().pullupLoading();
- });
- }
接下来我们分析代码是如何实现上述目的的。
首先我们来分析mui('#pullrefresh').pullRefresh()是怎么回事?
在mui.js中包含pullRefresh代码主要作用是初始化PullRefresh对象,但是针对iOS和Android是不同的,前者是js对象,后者是H5+对象。
H5版本的pullRefresh方法如下:
- $.fn.pullRefresh = function(options) {
- if (this.length === 1) {
- var self = this[0];
- var pullRefreshApi = null;
- options = options || {};
- var id = self.getAttribute('data-pullrefresh');
- if (!id) {
- id = ++$.uuid;
- $.data[id] = pullRefreshApi = new PullRefresh(self, options);
- self.setAttribute('data-pullrefresh', id);
- } else {
- pullRefreshApi = $.data[id];
- }
- if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次,在官方例子中,没有设置auto,因此在sub.html中主动调用了一次
- pullRefreshApi.pullupLoading();
- }
- return pullRefreshApi;
- }
- };
注意:后面的PlusPullRefresh是绑定在Webview整个dom的扩展,然后$.fn.pullRefresh对于全局有效(jquery的语法规则),因此 $container.pullrefresh就是调用的$.fn.pullRefresh
其中核心是:
1、返回了PullRefresh或PlusPullRefresh对象
2、如果up设置了auto属性为true,则自动调用up对应的上拉加载函数加载一起数据。
然后我们来看看pullRefresh如何调用的pullupLoading
我们可以看到,实际调用pullupLoading是通过pullRefreshApi的,而后者其实是pullupRefresh中创建的PullupRefresh对象的引用,该对象有个pullupLoading()方法,其将在mui.init中声明的options作为参数传到内部,new PullRefresh(self, options);。
- function($, window, document, undefined) {
- var CLASS_VISIBILITY = 'mui-visibility';
- var CLASS_HIDDEN = 'mui-hidden';
- var PullRefresh = $.Scroll.extend($.extend({
- handleEvent: function(e) {
- this._super(e);
- ........
- pullupLoading: function(callback, x, time) {
- x = x || 0;
- this.scrollTo(x, this.maxScrollY, time, this.options.bounceEasing);
- if (this.loading) {
- return;
- }
- this._initPullupRefresh();
- this._setCaption(this.options.up.contentrefresh);
- this.indicators.map(function(indicator) {
- indicator.fade(0);
- });
- this.loading = true;
- callback = callback || this.options.up.callback;
- callback && callback.call(this);
- },
从callback= callback || this.options.up.callback;可以看出pullupLoading方法中调用了up.callback,callback.call(this)。换言之,mui('#pullrefresh').pullRefresh().pullupLoading();等于是调用了 pullupRefresh //上拉加载具体业务实现 方法。
那为什么this.options.up.callback对应的就是pullupFresh呢?
那么pullupLoading是如何调用up对应pullupRefresh自定义方法的?
简而言之,是因为在初始化时,将pullupRefresh方法赋值给了up的callback方法。如下代码所示。
- mui.init({
- pullRefresh: {
- container: '#pullrefresh',
- down: {
- callback: pulldownRefresh //下拉刷新具体业务实现
- },
- up: {
- contentrefresh: '正在加载...',
- callback: pullupRefresh //上拉加载具体业务实现
- }
- }
- });
那么这个mui.init调用的pullRefresh具体代码是如何进行参数传递的呢?
- **
- * mui.init pulldownRefresh
- * @param {type} $
- * @returns {undefined}
- */
- (function($) {
- $.registerInit({
- name: 'pullrefresh',
- index: 1000,
- handle: function() {
- <span style="color: #ff0000;">var options = $.options;</span>
- var pullRefreshOptions = options.pullRefresh || {};
- var hasPulldown = pullRefreshOptions.down && pullRefreshOptions.down.hasOwnProperty('callback');
- var hasPullup = pullRefreshOptions.up && pullRefreshOptions.up.hasOwnProperty('callback');
- if (hasPulldown || hasPullup) {
- var container = pullRefreshOptions.container;
- if (container) {
- var $container = $(container);
- if ($container.length === 1) {
- if ($.os.plus && $.os.android) { //android 5+
- $.plusReady(function() {
- var webview = plus.webview.currentWebview();
- if (hasPullup) {
- //当前页面初始化pullup
- var upOptions = {};
- upOptions.up = pullRefreshOptions.up;
- upOptions.webviewId = webview.id || webview.getURL();
- $container.pullRefresh(upOptions);
- }
- if (hasPulldown) {
- var parent = webview.parent();
- var id = webview.id || webview.getURL();
- if (parent) {
- if (!hasPullup) { //如果没有上拉加载,需要手动初始化一个默认的pullRefresh,以便当前页面容器可以调用endPulldownToRefresh等方法
- $container.pullRefresh({
- webviewId: id
- });
- }
- var downOptions = {
- webviewId: id
- };
- downOptions.down = $.extend({}, pullRefreshOptions.down);
- downOptions.down.callback = '_CALLBACK';
- //父页面初始化pulldown
- parent.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify(downOptions) + "')");
- }
- }
- });
- } else {
- $container.pullRefresh(pullRefreshOptions);
- }
- }
- }
- }
- }
- });
- })(mui);
- /**
其中$container是从mui.init中的pullRefresh初始化的参数中来的:
- var container = pullRefreshOptions.container;
就是containers等于id为pullreresh的那个div。
这段代码的核心是:
1、 通过调用$container.pullRefresh(pullRefreshOptions);, 将sub.html中配置的container,up,down这些options都传给了PullRefresh对象。
2、也是通过上述代码,初始化了PullRefresh对象。
总结:
1、在mui.init中通过调用pullRefresh将container,up,down等参数传入初始化了PullRefresh对象(针对iOS使用H5),或PlusPullRefresh对象(针对Android使用HTML5+)
2、在mui('#pullrefresh').pullRefresh().pullupLoading();中完成了表格初始化加载。调用了up对应的pullupRefresh方法。
3、当下拉刷新时,调用down对应的方法pulldownRefresh;当上拉加载时,调用up调用的方法pullupRefresh;
4、在pullupRefresh和pullupRefresh中利用ajax实现远程数据加载。
5、在mui.init中初始化pullRefresh时,可以通过参数来设置显示的话术,不写的话默认也有话术,见源代码。
- up:{contentrefresh:"正在加载...",//可选,正在加载状态时,上拉加载控件上显示的标题内容
- contentnomore:'没有更多数据了',//可选,请求完毕若没有更多数据时显示的提醒内容;
==================================================================================================================
var count = 0; /** * 上拉加载具体业务实现 */ function pullupRefresh() { setTimeout(function() { mui('#pullrefresh').pullRefresh().endPullupToRefresh((++count > 2)); //参数为true代表没有更多数据了。 var table = document.body.querySelector('.mui-table-view'); var cells = document.body.querySelectorAll('.mui-table-view-cell'); for (var i = cells.length, len = i + 20; i < len; i++) { var li = document.createElement('li'); li.className = 'mui-table-view-cell'; li.innerHTML = '<a class="mui-navigate-right">Item ' + (i + 1) + '</a>'; table.appendChild(li); } }, 1500); }
下面分析一下上拉加载的代码,同时它也是表格初始化的代码。
mui('#pullrefresh').pullRefresh().endPullupToRefresh((++count > 2)); //参数为true代表没有更多数据了。
这句代码用于显示没有更多数据这句话,并结束上拉。由于官方案例主要用于模拟,因此它的终止条件是上拉2次,但是初始化表格还算一次,因此count最终等于3而终止上拉。
如果是真实项目,应该是先用Ajax从远程或storage从本地加载数据,应该从Server返回一个属性标识是否后续还有数据。
同时还需要考虑首次加载和上拉加载的参数传递。
假设列表是按照item的id排序(假设id是自增序列),首次加载从max(item_id)返回20条数据,这样上拉加载时就告知server当前列表底部最后一条数据的id,然后server返回比该id更小的20条数据。当下拉刷新时,向服务器请求id大于列表顶端的item。
rest api:上拉加载 1、/list/load 加载最新的20条,select * from list orderby id limit 20
2、/list/load?startId={列表底部item的id} select * from list where id<{列表底部item的id} limit 20
如果返回的结果小于20,那说明已经到底儿了,返回给客户端告知isEnd:ture
下拉刷新 :/list/load?endId={列表顶部item的id} select * from list where id>{列表顶部item的id} orderby id limit 20
如果新的数据大于20,也不可能一次都拉过来,上述sql返回离现在最近的20条,余下的可以采用循环拉取方式,比如发现select回来加了limi限制的数据和select count(*) from list where id>{列表顶部item的id} 相比更少,可以再次发起请求拉取,/list/load?endId={本次下拉刷新操作前列表顶部item的id} & startId={上次取回的数据最小的id}, select * from list where id>{本次下拉刷新操作前列表顶部item的id} and id<{上次取回的数据最小的id} orderby id limit 2,然后拿回来的数据再次与select count(*) from list where id>{本次下拉刷新操作前列表顶部item的id} and id<{上次取回的数据最小的id}比如果还是小,那么告知客户端继续拉取。
另一种方式是将之前的数据清掉,保证可以触发上拉加载事件(不知道MUI是否支持)
其实如果量不大,就一次性都拉过来也可以,也就是去掉limit 20的限制。
返回的结果集json:
var result={"list":[
{"item_id":1,"item_content":"Hello cat"}, {"item_id":2,"item_content":"Hello dog"}
],"isEnd":true}
相关推荐
mui框架基于htm5plus的XMLHttpRequest,封装了常用的Ajax函数,支持GET、POST请求方式,支持返回json、xml、html、text、script数据类型; 本着极简的设计原则,mui...那么如何实现下拉刷新,上拉加载的功能呢? 首先
新闻信息列表必备的功能,支持Table,Ul等列表. 以下是DIV版本,在安卓端或者ios端必须使用双webview模式,传送门:...--下拉刷新容器--> <!--数据列表--> <script type=text/javascr
仅需两步轻松完成完整分页逻辑(翻页刷新,上拉加载更多),分页自动处理。支持自定义加载更多的文字或整个视图,自定义拖放刷新样式,自动管理空数据视图,支持吸顶效果等。 在DCloud插件市场中访问: ://ext....
io.dcloud.application.DCloudApplication.apk
利用VC++并结合OPENGL实现三维点云的显示并可以用鼠标转动从各个角度观察
DCloud技术安卓打包,清单配置文件的示例代码
BUI-webapp控件-DCloud打包, 基于DCloud打包的webapp, 控件示例, 可以安装一致的体验
3DCloud照片建模基本教程,文档类型word. 本文档介绍了从镜头选型、相机设置、光圈参数、场景条件要求、照片处理等都做了详细说明。
这个包是h5+源码的形式;本来要传三个 太大就算了 我一般有2个 第一个就是这个h5+插件源码;这样方便调试 第二个是把插件源码拿出来打包成jar文件,这是最终效果 另外,打包jar的话注意资源文件的引用方式
1、 DCloud介绍和产品架构_高清;2、官方的文档和工具案例展示_高清;3、 用HBuilder开发一个HelloWorld_高清;4、 页面构成、跳转和网络通讯_高清;5、页面构成-创建子页面_高清;等等
云端用于与DCloud接口的SDK用法一个简单的用法示例: import 'package:d_cloud/d_cloud.dart' ;Future < void> main () async { final dCloud = DCloud (apiKey : 'your-api-key' , apiSecret : 'your-secret-key' )...
这个项目中调用的原生界面是loginsdk.aar中的界面,这里使用的是Dcloud插件方式去调用原生界面,并且正确获取原生界面返回给前端页面的数据,有不懂的朋友可以参考一下。
这里是利用DCloud公司产品做出的开源项目集锦。 注意,所有开源项目并非全部托管在当前工程下,点击如下开源项目,会自动跳转到对应代码托管地址。 资讯类 新闻阅读器 开发者新闻APP 红旅动漫 闪读看书 电商类 灰...
dCloud GC overview slides for Nanjing Partner Event
Dcloud html5 打开通讯录获取联系人
基于uni-app的Dcloud底部导航栏!
ysy.dcloud_4.2.0_105.apk.1
1、Dcloud云开发(无需服务器和域名) 2、自动采集头像、套图 3、支持用户投稿,后台审核 4、支持后端修改/增加轮播图 5、前端即可进行日常管理 6、功能强大,支持多图上传 7、看广告赚积分方式,可对接小程序流量主...