转载

使用 Dojo Mobile 1.9 的新特性实现分页显示

Dojo Mobile 是一个基于 dojo 的用于开发移动应用的组件库,里面提供了许多用来构建移动用户界面的轻量级组件。开发者通过这些组件和皮肤可以开发出跟原生移动应用体验非常接近的移动设备客户端界面。

dojox/mobile/ScrollableView 是一个占满整个移动设备屏幕的容器 Widget,并且可以通过触摸来上下滚动其中的内容。从 Dojo Mobile 1.9 起,它新增了一个新事件 onBeforeScroll 用来响应用户的滚动操作是否正在进行。它的事件参数 e 包含 6 个重要属性:

  1. X:滚动到达的 x 坐标
  2. y:滚动到达的 y 坐标
  3. beforeTop:一个布尔值,当滚动到达的位置超过 ScrollableView 最顶端的时候为 true,否则为 false
  4. beforeTopHeight:滚动到达的位置超过最顶端的距离的像素值
  5. afterBottom:一个布尔值,当滚动到达的位置超过 ScrollableView 最底端的时候为 true,否则为 false
  6. afterBottomHeight:滚动到达的位置超过最底端的距离的像素值

加上它在 Dojo Mobile 之前的版本里就有的 onTouchEnd 事件,我们可以很方便的实现很多在当今手机应用中用户喜闻乐见的交互模式。

回页首

下拉刷新示例

首先,在页面上新建一个 dojox/mobile/ScrollableView。

清单 1. HTML

<div id="sview" data-dojo-type="dojox.mobile.ScrollableView">  <h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Pull down to refresh</h1>  <div id="pullToRefreshPanel" style="display: none;">  <div><div></div></div>  </div>  <ul id="rlist" data-dojo-type="dojox.mobile.RoundRectList">  <li data-dojo-type="dojox.mobile.ListItem">Item 1</li>   ……  <li data-dojo-type="dojox.mobile.ListItem">Item 10</li>  </ul> </div>

这个 Scrollable View 里包含三个部分:

  1. 一个 dojox/mobile/Heading ,相当于 此页面的 Title
  2. 一个 隐藏的 pullToRefreshPanel div,稍后用来显示用户的下拉效果。
  3. 一个 dojox/mobile/RoundRectList 里包含了十条 dojox/mobile/ListItem 模拟数据,表示第一页的查询结果。

图 1. 初始化页面

使用 Dojo Mobile 1.9 的新特性实现分页显示

然后,定义显示用户下拉效果的 pullToRefreshPanel div。

清单 2. CSS

#pullToRefreshPanel {  position: absolute;  top: 0px;  width: 100%;  z-index: 100;  font-weight: bold;  overflow: hidden;  background-color: #E4E7EE;  padding-left: 20px; } #pullToRefreshPanel > div {  position: inherit;  bottom: 12px;  padding-left: 22px;  width: 100%;  height: 100%;  color: #6E8098;  background-repeat: no-repeat;  background-position: bottom left; } #pullToRefreshPanel > div > div {  position: absolute;  bottom: 4px; } .pullDownToUpdate > div {  background-image: url('images/pull-arrow.png'); } .pullDownToUpdate > div > div:before {  content: "Please continue to pull down"; } .releaseToUpdate > div {  background-image: url('images/release-arrow.png'); } .releaseToUpdate > div > div:before {  content: "Please release"; }

其中的两个图片为向下和向上的两个箭头,指示用户此时应该向哪个方向滑动手指。

图 2. 下拉高度未达到 80 像素

使用 Dojo Mobile 1.9 的新特性实现分页显示

图 3. 下拉高度超过 80 像素

使用 Dojo Mobile 1.9 的新特性实现分页显示

最后,添加页面初始化之后需要用到的脚本。

清单 3. JavaScript

require([  "dojo/ready",  "dojo/on",  "dojo/dom",  "dojo/dom-class",  "dijit/registry",  "dojox/mobile/parser",  "dojox/mobile",  "dojox/mobile/compat",  "dojox/mobile/ScrollableView",  "dojox/mobile/Heading",  "dojox/mobile/RoundRect",  "dojox/mobile/RoundRectList" ], function(ready, on, dom, domClass, registry){  ready(function(){  var pullToRefreshPanel = dom.byId("pullToRefreshPanel");  var scrollableView = registry.byId("sview");  var recordList = registry.byId("rlist");  var pullToRefreshPanelDisplayed = false;  var refreshOnTouchEnd = false;  var index = 10;  var total = 25;   var displayPullToRefreshPanel = function() {  pullToRefreshPanelDisplayed = true;  pullToRefreshPanel.style.display="block";  };  var hidePullToRefreshPanel = function() {  pullToRefreshPanelDisplayed = false;  pullToRefreshPanel.style.display="none";  };   scrollableView.on("beforescroll", function(evt){  if(evt.beforeTop){  // 显示 pullToRefreshPanel 面板  if(!pullToRefreshPanelDisplayed){  displayPullToRefreshPanel();  }  // 根据用户手指的滑动距离调整 pullToRefreshPanel 面板的显示高度  pullToRefreshPanel.style.height= evt.beforeTopHeight + "px";  pullToRefreshPanel.style.top= -evt.beforeTopHeight + "px";  }else{  // 隐藏 pullToRefreshPanel 面板  if(pullToRefreshPanelDisplayed){  hidePullToRefreshPanel();  }  }  if(evt.beforeTopHeight > 80){  domClass.remove(pullToRefreshPanel, "pullDownToUpdate");  domClass.add(pullToRefreshPanel, "releaseToUpdate");  refreshOnTouchEnd = true;  }else{  domClass.remove(pullToRefreshPanel, "releaseToUpdate");  domClass.add(pullToRefreshPanel, "pullDownToUpdate");  refreshOnTouchEnd = false;  }  });   scrollableView.on("touchend", function(evt){  // 用户手指的滑动操作结束,手指已经抬起离开屏幕  // 隐藏 pullToRefreshPanel 面板  if(pullToRefreshPanelDisplayed){  hidePullToRefreshPanel();  }  // 刷新页面  if(refreshOnTouchEnd){  refreshOnTouchEnd = false;  // 清空数据列表  registry.byId("rlist").destroy();  var newRecordList = new dojox.mobile.RoundRectList({id:"rlist"});  var remain = total - index;  if(remain > 10){  for(var i=0;i<10;i++){  newRecordList.addChild(new dojox.mobile.ListItem({label:"Item "+ ++index}));  }  } else {  // 到达最后一页  for(var i=0;i<remain;i++){  newRecordList.addChild(new dojox.mobile.ListItem({label:"Item "+ ++index}));  }  newRecordList.addChild(new dojox.mobile.ListItem({label:"No more records"})); index = 0;  }  scrollableView.addChild(newRecordList);  }  });  }); });

请注意以上代码中绑定至 ScrollableView 的加粗的新事件。首先,我们用 beforeScroll 来监听用户此时是否正在滑动 ScrollableView,evt.beforeTop 为 true 就表示用户正在向下滑动而且已经超过了 ScrollableView 的最顶端,那么这时应该显示预先隐藏在 ScrollableView 里的 pullToRefreshPanel div 并将它的高度设成 evt.beforeTopHeight,跟用户滑动手指的高度一致。这时候 pullToRefreshPanel 显示的图片是个向下箭头,提示用户“请继续下拉”,那么用户会继续向下滑动手指而不松开。直到用户向下滑动的高度大于 80 个像素,pullToRefreshPanel 显示的图片会变成向上箭头,提示用户“请松手”,那么用户松开手指后就触发了 touchEnd 事件。在 touchEnd 事件的处理函数中先隐藏 pullToRefreshPanel div,然后在 ScrollableView 里删除之前的十条数据并显示接下来的十条数据。这样,就完成了一次下拉刷新的功能,这个过程可以反复发生直到显示最后一页。

图 4. 页面刷新显示第二页的数据

使用 Dojo Mobile 1.9 的新特性实现分页显示

图 5. 页面刷新显示最后一页的数据

使用 Dojo Mobile 1.9 的新特性实现分页显示

接下来,我们举一反三,如果要实现像微信那样,下拉之后并不删除之前的数据,而是在顶部加载新数据,该怎么做呢?

回页首

下拉加载更多

很简单,只需要把脚本里 touchEnd 事件的处理函数对应的地方改成这样就行了:

清单 4. JavaScript

if(refreshOnTouchEnd){  refreshOnTouchEnd = false;  // 这次不用清空数据列表  var recordListDom = recordList.domNode;  var remain = total - index;  if(remain > 10){  for(var i=0;i<10;i++){  recordListDom.insertBefore(new dojox.mobile.ListItem({label:"Item "+ ++index}).domNode,     recordListDom.firstChild);  }  } else {  // 到达最后一页  for(var i=0;i<remain;i++){  recordListDom.insertBefore(new dojox.mobile.ListItem({label:"Item "+ ++index}).domNode,     recordListDom.firstChild);  }  recordListDom.insertBefore(new dojox.mobile.ListItem({label:"No more records"}).domNode,      recordListDom.firstChild);  } }

图 6. 下拉加载到最后一页的效果

使用 Dojo Mobile 1.9 的新特性实现分页显示

现在,我们反过来,把下拉变成上拉,在界面底端实现刷新又该怎么做?

回页首

上拉刷新示例

还是在下拉刷新的代码基础上进行改动,需要替换的代码如下:

  1. 把所有代码里的“Pull down”替换成“Pull up”。
  2. 把 CSS 里所有的 top 换成 bottom,bottom 换成 top,然后把两个箭头图片的名字对换一下。
  3. 把 beforeScroll 事件里的 evt.beforeTop 换成 evt.afterBottom,evt.beforeTopHeight 换成 evt.afterBottomHeight,pullToRefreshPanel.style.top 换成 pullToRefreshPanel.style.bottom。

图 7. 上拉高度未达到 80 像素

使用 Dojo Mobile 1.9 的新特性实现分页显示

图 8. 上拉高度超过 80 像素

使用 Dojo Mobile 1.9 的新特性实现分页显示

最后一种情况是上拉加载更多,比下拉加载更多的功能实现起来要简单,因为不是在列表最顶端插入元素,而是在末尾。

回页首

上拉加载更多

在上拉刷新的代码基础上,只需要把脚本里 touchEnd 事件的处理函数对应的地方改成这样就行了:

清单 5. JavaScript

if(refreshOnTouchEnd){  refreshOnTouchEnd = false;  // 这次不用清空数据列表  var remain = total - index;  if(remain > 10){  for(var i=0;i<10;i++){  recordList.addChild(new dojox.mobile.ListItem({label:"Item "+ ++index}));  }  } else {  // 到达最后一页  for(var i=0;i<remain;i++){  recordList.addChild(new dojox.mobile.ListItem({label:"Item "+ ++index}));  }  recordList.addChild(new dojox.mobile.ListItem({label:"No more records"}));  }  }

图 9. 上拉加载到最后一页的效果

使用 Dojo Mobile 1.9 的新特性实现分页显示

回页首

结束语

本文介绍了如何使用 Dojo Mobile 1.9 的新特性在移动应用中方便快速的实现常用的分页显示功能,然后举一反三,一并介绍了由此扩展的另外三种交互模式。通过学习具体的示例代码,读者可以在自己的查询功能中灵活运用这些方法。

回页首

示例代码

实例代码中的文件可以直接拷贝至 Dojo 源代码库里的 dojox/mobile/tests 路径下,双击运行。

回页首

下载

描述 名字 大小
示例代码 codes.zip 7KB
正文到此结束
Loading...