文档章节

xmlplus 组件设计系列之五 - 选项卡(Tabbar)

qudou
 qudou
发布于 2017/04/26 11:39
字数 1168
阅读 55
收藏 0

选项卡

这一章将设计一个选项卡组件,选项卡组件在手持设备上用的比较多,下面是一个示意图:

<img src="http://www.xmlplus.cn/img/tabbar.png" class="img-responsive"/>

选项卡组成

在具体实现之前,想像一下目标组件是如何使用的,对于设计会有莫大的帮助。通过观察,可以将选项卡组件分为容器部分和子项部分,正如下面的 XML 结构所展示的。

<!-- 05-01 -->
<Tabbar id="tabbar">
    <TabItem id="home" label="首页"/>
    <TabItem id="setting" label="设置"/>
    <TabItem id="logs" label="日志"/>
    <TabItem id="about" label="关于"/>
</Tabbar>

现在我们把目光切换到选项卡组件的子项部分,来看看子项部分是如何分解的。通过示意图,你可以发现子项部分可以分解为子项容器以及包含一个图标和一个文本的子级部分。

<!-- 05-01 -->
<a id="tabitem">
    <Icon id="icon"/>
    <span id="label">首页</span>
</a>

所以,现在我们的目标已经很明确了,主要设计三个组件:图标组件 Icon、选项卡组件的子项 TabItem 以及选项卡组件的容器 Tabbar。

结构图

由于该组件比较简单,所以可以将三种子组件放置在同一层级。但请注意,我们还有四个图标组件,可以创建一个子级用于容纳它们。下面给出我们的组件结构图:

Tabbar/
├── Tabbar
├── TabItem
└── Icon/
     ├── About
     ├── Home
     ├── Logs
     └── Setting

图标的实现

我们从最简单的开始,先看四个图标组件,图标组件主要通过封装 SVG 文本来实现,由于图标文本较长,所以这里仅截取每个图标文本的一段。

// 05-01
About: {
    xml: `<svg width="48" height="48" viewBox="0 0 1024 1024">
               <path d="M507.577907 23.272727C240.142852..."/>
          </svg>`
},
Home: {
    xml: `<svg width="48" height="48" viewBox="0 0 1024 1024">
               <path d="M949.082218 519.343245 508.704442..."/>
          </svg>`
},
Logs: {
    xml: `<svg width="48" height="48" viewBox="0 0 1024 1024">
               <path d="M576 125.344l32 0 0 64-32 0 0-64Z..."/>
          </svg>`
},
Setting: {
    xml: `<svg width="48" height="48" viewBox="0 0 1024 1024">
               <path d="M512 336.664c-96.68 0-175.336 78...."/>
          </svg>`
}

请注意,这些图标位于虚拟目录 /icon 之下,也就是你要像下面这样导入:

// 05-01
xmlplus("ui", function (xp, $_, t) {
    $_().imports({Tabbar: {... }, TabItem: {...}});

    $_("icon").imports({--这里包含了四个图标组件--});
});

下面来实现图标组件 Icon,这里的图标组件与上面是不同的,它会根据输入的图标类型实例化不同的图标。这样设计可以复用部分相同的代码,避免冗余。

// 05-01
Icon: {
    css: "#icon { width: 1.5em; height: 1.5em; display: inline-block; }",
    opt: { icon: "about" },
    xml: `<span id="icon"/>`,
    fun: function (sys, items, opts) {
        sys.icon.replace("icon/" + opts.icon).addClass("#icon");
    }
}

该组件的函数项根据输入的图标类型创建图标组件并替换已有的 span 元素对象。注意,替换完后需要重新添加样式。

子项的实现

按从内到外的原则,接下来实现选项卡组件的子项 TabItem。对于此组件,需要在组件的映射项中做一次异名的属性映射,把 id 属性值映射给内部的图标组件的 icon 属性。

// 05-01
TabItem: {
    css: `a#tabitem { display: table-cell; overflow: hidden; width: 1%; height: 50px; text-align: center; ... }
          #label { display: block; font-size: .75em; overflow: hidden; text-overflow: ellipsis; -webkit-user-select: none; }
          a#primary { color: #337ab7; fill: currentColor; }`,
    map: {"attrs": { icon: "id->icon" } },
    xml: `<a id="tabitem">
              <Icon id="icon"/>
              <span id="label">首页</span>
          </a>`,
    fun: function (sys, items, opts) {
        sys.label.text(opts.label);
        function select(bool) {
            sys.tabitem[bool ? 'addClass' : 'removeClass']("#primary");
        }
        return Object.defineProperty({}, "selected", { set: select});
    }
}

此组件提供了用于选项切换时选中与非选中状态之间切换的接口。以供选项卡容器使用。

选项卡的实现

最后来看下选项卡组件 Tabbar 的实现。该组件侦听了用户触击选项卡时的事件,在侦听器里主要做两件事:一是维持选项卡状态的切换;另一是派发一选项卡切换时的状态改变事件。

// 05-01
Tabbar: {
    css: `#tabbar { display: table; width: 100%; height: 50px; padding: 0; table-layout: fixed; -webkit-touch-callout: none; }
          #tabbar { z-index: 10; background-color: #f7f7f7; backface-visibility: hidden; }`,
    xml: `<nav id="tabbar"/>`,
    fun: function (sys, items, opts) {
        var sel = this.first();
        this.on("touchend", "./*[@id]", function (e) {
            sel.value().selected = false;
            (sel = this).value().selected = true;
            this.trigger("switch", this.toString());
        });
        if (sel) sel.value().selected = true;
    }
}

至此,一个选项卡组件算是完成了,下面来看下具体的一个测试示例。注意,最好在 chrome 浏览器的移动模式下做测试,这样 touchend 事件才会生效。

// 05-01
Index: {
    xml: `<Tabbar id="index">
              <TabItem id="home" label="首页"/>
              <TabItem id="setting" label="设置"/>
              <TabItem id="logs" label="日志"/>
              <TabItem id="about" label="关于"/>
          </Tabbar>`,
    fun: function (sys, items, opts) {
        this.on("switch", (e, target) => console.log(target));
    }
}

在组件 Index 中,你可以侦听来自选项卡的切换事件来做相应的操作。比如结合后续我们介绍的视图栈组件做页面之间的切换操作。

© 著作权归作者所有

共有 人打赏支持
qudou

qudou

粉丝 5
博文 11
码字总数 14933
作品 2
福州
程序员
私信 提问
全栈 JavaScript 框架 xmlplus 1.5.9 发布

该版本主要对全局函数 clearLibrary 作了简化,另外对文档的一些文字错误进行了修正,同时保持了 gitHub 与 npm 版本之间的同步。 xmlplus 是一个设计非常独特 JavaScript 框架,用于快速开发...

qudou
2017/04/30
3.8K
16
xmlplus v1.5.8 正式发布 - 全栈 JavaScript 框架

全栈 JavaScript 框架 xmlplus v1.5.8 正式发布 xmlplus 是一个设计非常独特 JavaScript 框架,用于快速开发前后端项目。 基于组件设计 在 xmlplus 中,组件是基本的构造块。评价组件设计好坏...

qudou
2017/04/27
677
2
全栈 JavaScript 框架--xmlplus

xmlplus 是一个设计非常独特 JavaScript 框架,用于快速开发前后端项目。 基于组件设计 在 xmlplus 中,组件是基本的构造块。评价组件设计好坏的一个重要标准是封装度。基于 xmlplus 设计的组...

qudou
2017/04/21
1K
1
JavaScript 框架 xmlplus 1.5.12 发布

JavaScript 框架 xmlplus 1.5.12 发布了。xmlplus 是一个设计非常独特 JavaScript 框架,用于快速开发前后端项目。 这个版本主要添加了一个全局接口 create。该函数是一个轻量的用于创建组件...

qudou
2017/05/24
528
0
移动开发之微信小程序——资料集合

本文转载自:知乎 有需要下载的客官可可以点击知乎去下载相关资料 一:官方地址集合: 1:官方工具:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=1476434678461 2:...

DJY1992
2016/12/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

用any-loader封装jQuery的XHR —— 随便写着玩系列

哎,都说没人用JQuery啦,叫你别写这个。 其实我也是好高骛远使用过npm上某个和某个很出名的XHR库,嗯,认识我的人都知道我喜欢喷JQ,以前天天喷,见面第一句,你还用JQ,赶紧丢了吧。但我也...

曾建凯
今天
4
0
聊聊storm的AggregateProcessor的execute及finishBatch方法

序 本文主要研究一下storm的AggregateProcessor的execute及finishBatch方法 实例 TridentTopology topology = new TridentTopology(); topology.newStream("spout1", spout......

go4it
今天
3
0
大数据教程(7.5)hadoop中内置rpc框架的使用教程

博主上一篇博客分享了hadoop客户端java API的使用,本章节带领小伙伴们一起来体验下hadoop的内置rpc框架。首先,由于hadoop的内置rpc框架的设计目的是为了内部的组件提供rpc访问的功能,并不...

em_aaron
今天
5
0
CentOS7+git+github创建Python开发环境

1.准备CentOS7 (1)下载VMware Workstation https://pan.baidu.com/s/1miFU8mk (2)下载CentOS7镜像 https://mirrors.aliyun.com/centos/ (3)安装CentOS7系统 http://blog.51cto.com/fengyuns......

枫叶云
昨天
3
0
利用ibeetl 实现selectpicker 的三级联动

1. js 直接写在html页面上面,ibeetl 就可以动态地利用后台传上来的model List ,不需要每次点击都要ajax请求后台 2. 使用selectpicker 的时候,除了对selecct option的动态处理后,还需要 $("#...

donald121
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部