“下拉刷新”由著名设计师 Loren Brichter 设计,并应用于 Twitter 第三方应用 Tweetie 中。2010年4月,Twitter 收购 Tweetie 开发商 Atebits 后,该专利归 Twitter 所有。这一章我们就来看看如何实现一个简单的下拉刷新组件。
目标组件分析
和前面在设计组件时的做法一样,我们先想想看最终的成品组件是如何使用的,这需要点想像力。下拉刷新组件看成一个容器组件是合理的,用户可以对容器的内容进行下拉操作。如果用户完成了完整的下拉触发操作,该组件应该会有下拉完成的事件反馈,假定这个事件名为 ready。根据以上的分析,我们很有可能得到下面的一个该组件的应用示例。
Example1: {
xml: `<PullRefresh id='example'>
<h1>Twitter</h1>
<h2>Loren Brichter</h2>
</PullRefresh>`,
fun: function (sys, items, opts) {
sys.example.on("ready", () => console.log("ready"));
}
}
示例中的使用方式是非常简洁的,但我们还漏了一点。如果你用过一些新闻客户端,在某些情况下,此客户端会自动触发下拉刷新操作。比如,刚进入客户端页面或者由于软件推送机制产生的被动列表更新,这都将导致客户端下拉刷新操作的触发。所以如上的 PullRefresh 组件还应该提供一个触发自动刷新的操作接口。好了,下面是加入下拉刷新接口的应用示例。
Example2: {
xml: `<PullRefresh id='example'>
<h1>Twitter</h1>
<h2>Loren Brichter</h2>
<button id='refresh'>click</button>
</PullRefresh>`,
fun: function (sys, items, opts) {
sys.example.on("ready", () => console.log("ready"));
sys.refresh.on("click", items.example.refresh);
}
}
基本框架
现在让我们把目光转移到下拉刷新组件的内部,看看该如何去实现。观察文章开始部分的大图,很自然地我们可以将整个组件划分为三个子组件,如下面的 XML 文档所示。
<div id="refresh"> <Status id="status"/> <div id="content"></div> </div>
外围 div 元素包含两个子组件:其中一个是状态指示条,用于显示“下拉刷新”、“松开刷新”、“加载中...”以及“刷新成功”四个状态提示,这里暂时使用未定义的 Status 组件替代;另一个 div 元素用于容纳下拉刷新组件的包含内容。到现在,大概可以想得出该组件的工作逻辑了,于是我们可以给出下面的一个基本的组件框架。
PullRefresh: {
css: "#refresh { position: relative; height: 100%;...}",
xml: `<div id="refresh">
<Status id="status"/>
<div id="content"/>
</div>`,
map: { appendTo: "content" },
fun: function (sys, items, opts) {
sys.content.on("touchstart", e => {
// 侦听 touchmove 和 touchend事件
});
function touchmove(e) {
// 1 处理状态条与内容内面跟随触点移动
// 2 根据触点移动的距离显示相当的状态条内容
}
function touchend(e) {
// 1 移除 touchmove 和 touchend 事件
// 2 根据触点移动的距离决定返回原始状态或者进入刷新状态并派发事件
}
}
}
状态条的实现
如前面提到的,状态条组件包含四个状态提示,并且每一时刻仅显示一个状态。对于状态的切换,这里会先用到我们下一章将讲到的路由组件 ViewStack,这里仅需要了解如何使用即可。组件 ViewStack 对外只显示子级的一个子组件,同时侦听一个 switch 事件,该事件的派发者携带了一个切换到的目标对象的名称,也就是 ID。该组件根据这个 ID 来切换到目标视图。下面是状态条组件的完整实现。
Status: {
css: "#statusbar { height: 2.5em; line-height: 2.5em; text-align: center; }",
xml: <ViewStack id="statusbar">
<span id="pull">下拉刷新</span>
<span id="ready">松开刷新</span>
<span id="loading">加载中...</span>
<span id="success">刷新成功</span>
</ViewStack>,
fun: function (sys, items, opts) {
var stat = "pull";
function getValue() {
return stat;
}
function setValue(value) {
sys.statusbar.trigger("switch", stat = value);
}
return Object.defineProperty({}, "value", { get: getValue, set: setValue });
}
}
该组件提供一个 value 接口用户设置与获取组件的显示状态。父级组件可根据不同的时机调用该接口。
最终实现
有了上面的储备,让我们来填充完下拉刷新组件的细节。下拉刷新过程中会涉及到动画,对于动画目前一般有两种选择,可以使用 JQuery 动画函数,也可以是 css3,这需要看各人喜好了。这里我们选择使用 css3 来实现。为清晰起见,下面的实现仅给出函数部分,其余部分同上。
PullRefresh: {
fun: function (sys, items, opts) {
var startY, height = sys.status.height();
sys.content.on("stouchstart", e => {
if (items.status.value == "pull") {
startY = e.y;
sys.content.on("touchmove", touchmove).on("touchend", touchend);
sys.content.css("transition", "").prev().css("transition", "");
}
});
function touchmove(e) {
var offset = e.y - startY;
if ( offset > 0 ) {
sys.content.css("top", offset + "px");
sys.status.css("top", (offset - height) + "px");
items.status(offset > height ? "ready" : "pull");
}
}
function touchend (e) {
var offset = e.y - startY;
sys.content.off("touchmove").off("touchend");
sys.content.css("transition", "all 0.3s ease-in 0s").prev().css("transition", "all 0.3s ease-in 0s");
if ( offset < height ) {
sys.content.css("top", "0").prev().css("top", -height + "px");
} else {
items.status.value = "release";
sys.refresh.once("complete", complete);
sys.content.css("top", height + "px").prev().css("top", "0").trigger("ready");
}
}
function complete() {
items.status.value = "message";
setTimeout(() => {
sys.content.css("top", "0").prev().css("top", -height + "px");
sys.content.once("webkitTransitionEnd", e => items.status.value = "pull");
}, 300);
}
}
}
对于稍微有点复杂的组件,需要注意组件的组织归类,尽量把具有相近功能的组件放在一起。为了便于叙述,上述所列出的组件示意总把它们视作是同一目录,这一点读者应该能看出来。
本系列文章基于 xmlplus 框架。如果你对 xmlplus 没有多少了解,可以访问 www.xmlplus.cn。这里有详尽的入门文档可供参考。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# xmlplus
# 下拉刷新
# xmlplus组件设计系列之网格(DataGrid)(10)
# xmlplus组件设计系列之文本框(TextBox)(3)
# xmlplus组件设计系列之选项卡(Tabbar)(5)
# xmlplus组件设计系列之路由(ViewStack)(7)
# xmlplus组件设计系列之分隔框(DividedBox)(8)
# xmlplus组件设计系列之树(Tree)(9)
# xmlplus组件设计系列之按钮(2)
# xmlplus组件设计系列之列表(4)
# xmlplus组件设计系列之图标(ICON)(1)
# 客户端
# 让我们
# 我们可以
# 提供一个
# 如何使用
# 切换到
# 如果你
# 文档
# 会有
# 加载中
# 好了
# 你对
# 只显示
# 可以使用
# 可供
# 用过
# 该如何
# 能看
# 所示
# 其中一个
相关文章:
成都网站制作报价公司,成都工业用气开户费用?
深圳网站制作费用多少钱,读秀,深圳文献港这样的网站很多只提供网上试读,但有些人只要提供试读的文章就能全篇下载,这个是怎么弄的?
制作网站的模板软件,网站怎么建设?
如何在局域网内绑定自建网站域名?
建站之星如何实现五合一智能建站与营销推广?
活动邀请函制作网站有哪些,活动邀请函文案?
常州自助建站费用包含哪些项目?
建站主机选购指南:核心配置优化与品牌推荐方案
如何设计高效校园网站?
广州网站建站公司选择指南:建站流程与SEO优化关键词解析
如何选择高效稳定的ISP建站解决方案?
北京网站制作的公司有哪些,北京白云观官方网站?
c# Task.ConfigureAwait(true) 在什么场景下是必须的
行程制作网站有哪些,第三方机票电子行程单怎么开?
模具网站制作流程,如何找模具客户?
SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?
整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?
整蛊网站制作软件,手机不停的收到各种网站的验证码短信,是手机病毒还是人为恶搞?有这种手机病毒吗?
成都响应式网站开发,dw怎么把手机适应页面变成网页?
,想在网上投简历,哪几个网站比较好?
网站按钮制作软件,如何实现网页中按钮的自动点击?
网站制作的方法有哪些,如何将自己制作的网站发布到网上?
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
如何在搬瓦工VPS快速搭建网站?
如何高效利用200m空间完成建站?
ppt制作免费网站有哪些,ppt模板免费下载网站?
免费公司网站制作软件,如何申请免费主页空间做自己的网站?
建站之星客服服务时间及联系方式如何?
深圳企业网站制作设计,在深圳如何网上全流程注册公司?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
制作营销网站公司,淘特是干什么用的?
招商网站制作流程,网站招商广告语?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
制作电商网页,电商供应链怎么做?
Android自定义控件实现温度旋转按钮效果
如何通过PHP快速构建高效问答网站功能?
建站之星安全性能如何?防护体系能否抵御黑客入侵?
深圳网站制作案例,网页的相关名词有哪些?
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
如何通过可视化优化提升建站效果?
微信小程序 input输入框控件详解及实例(多种示例)
c++怎么用jemalloc c++替换默认内存分配器【性能】
平台云上自主建站:模板化设计与智能工具打造高效网站
网站制作新手教程,新手建设一个网站需要注意些什么?
宿州网站制作公司兴策,安徽省低保查询网站?
武汉网站制作费用多少,在武汉武昌,建面100平方左右的房子,想装暖气片,费用大概是多少啊?
做企业网站制作流程,企业网站制作基本流程有哪些?
如何快速辨别茅台真假?关键步骤解析
单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?
网站制作价目表怎么做,珍爱网婚介费用多少?
*请认真填写需求信息,我们会在24小时内与您取得联系。