1、UI2.0与UI1.0的对比
这样通过不同的组合可以生成多变的效果。在实际商用应用开发过程中,它起到了帮助我们加快开发进度的作用。但是在开发过程中,我们还是遇到了一些问题,JQMobile CSS框架在这些问题上,表现得比较乏力:
1、1 自动填充宽度
![](http://doc.appcan.cn/images/001.png)
上图中同样一个编辑框加上一个刷新按钮的组合。在不同分辨率下,如果希望,刷新按钮保持一个基本宽度,编辑框自动填充剩余区域,在不使用JS的情况下是很难做到的,如果使用百分比控制刷新钮的宽度,那么在低分辨率和高分辨率之间将会有非常大的偏差。
1、2 类名称过长
JQMobile方案中,为了帮助开发者能够更直观的了解代码,每一个功能类的名称都比较长。例如ui-page ui-mobile-viewport等。这造成了网页代码大小变大,降低了解析速度。
1、3 类功能拆分度低
在JQMobile方案中,很多类定义,代码重复较多,例如预制的多种色彩方案。同时由于拆分度低,经常需要重复定义类来覆盖其他类中的属性。
1、4 控件组合复杂
JQMobile方案中,控件的实现代码量很大,一个按钮需要多个div span嵌套配合多个类才能实现。这造成开发中,界面代码量增大,不好控制界面。
我们综合各个项目中的开发经验,整理汇总了AppCan UI2.0架构,它继承了UI1.0的优点,并很好地解决了UI1.0的问题,可以使开发能够更加的简单。UI2.0框架图如下:
![](http://doc.appcan.cn/images/003.jpg)
● 定位-对元素进行布局,确定元素的现实位置大小等[LAYOUT CLASS]
● 描边-对元素基础属性进行设定,例如边框圆角等[BASE CLASS]
● 添色-对元素的边框、文字和背景进行设定[COLOR CLASS]
● 插图-如果元素中需要图片,从资源中引入图片类[RES CLASS]
基于基础元素之上,为了方便开发者,我们重新定义了控件,包含BUTTON、LIST、FOLD、INPUT、TAB、RADIO、CHECK、SWITCH。这些控件可以认为是UI2.0框架的具体事例。通过UI2.0完成的控件,代码大小和复杂度,都有明显的降低,如下例:
UI1.0框架实现的按键
<div class="ui-btn ui-corner-all ui-shadow ui-btn-b">
<span class="ui-btn-inner ui-corner-all">
<span class="ui-btn-text ">确定</span>
</span>
</div>
UI2.0框架实现的按键
<div class="btn btn-act ubb uc-t1 b-bla uinn c-blu2 c-m4 ">确定 </div>
接着我们详细介绍如何使用UI2.0框架。
2、UI2.0框架的设计来源——弹性盒子模型
效果:
![](http://doc.appcan.cn/images/004.png)
<div style="display:inline;border:1px solid blue">
<div style="display:inline;background:#E00">aaaa </div>
<div style="display:inline;background:#0E0">bbbb </div>
</div>
效果:
![](http://doc.appcan.cn/images/006.png)
<div style="display:-webkit-box;width:200px;border:1px solid blue">
<div style="-webkit-box-flex:1;background:#E00">aaaa </div>
<div style="background:#0E0">bbbb </div>
</div>
我们再调整一下代码。
效果:
![](http://doc.appcan.cn/images/008.png)
<div style="display:-webkit-box;width:200px;border:1px solid blue">
<div style="-webkit-box-flex:1;background:#E00">aaaa </div>
<div style="-webkit-box-flex:2;background:#0EE">bbbb </div>
<div style="background:#0E0">cccc </div>
</div>
效果:
![](http://doc.appcan.cn/images/009.png)
<div style="display:-webkit-box;width:200px;border:1px solid blue">
<div style="-webkit-box-flex:1;background:#E00;position:relative">
<div style="position:absolute;width:100%;height:100%;">aaaa </div>
</div>
<div style="-webkit-box-flex:2;background:#0EE;position:relative">
<div style="position:absolute;width:100%;height:100%;">bbbb </div>
</div>
<div style="background:#0E0">cccc </div>
</div>
效果:
![](http://doc.appcan.cn/images/010.png)
<div style="display:-webkit-box;height:200px;border:1px solid blue;-webkit-box-orient:vertical;">
<div style="-webkit-box-flex:1;background:#E00;position:relative">
<div style="position:absolute;width:100%;height:100%;">aaaa </div>
</div>
<div style="-webkit-box-flex:2;background:#0EE;position:relative">
<div style="position:absolute;width:100%;height:100%;">bbbb </div>
</div>
<div style="background:#0E0">cccc </div>
</div>
弹性盒子模型还提供了其他几个强大的属性。
● -webkit-box-direction:reverse;
通过在父DIV中设定这个属性可以让子元素反向排列。如下图:
![](http://doc.appcan.cn/images/011.png)
● -webkit-box-align:center;
通过在父元素中设定这个属性,当子元素横向排布时,可以使子元素间实现上边界对齐、中线对齐和下边界对齐的效果
![](http://doc.appcan.cn/images/012.png)
![](http://doc.appcan.cn/images/013.png)
通过在父元素中设定这个属性,当子元素横向排布时,可以使子元素间左边界对齐、中线对齐和右边界对齐
![](http://doc.appcan.cn/images/013.png)
![](http://doc.appcan.cn/images/012.png)
弹性BOX架构可以同时兼容流式布局,即当所有子元素都没有设定弹性份数时,父元素可以被子元素自动撑开。如下代码
效果:
![](http://doc.appcan.cn/images/014.png)
<div style="display:-webkit-box;border:1px solid blue;-webkit-box-orient:vertical;">
<div>aaaa </div>
<div>bbbb </div>
<div>cccc </div>
</div>
在AppCan UI2.0架构中,我们把上面遇到的情况进行了CSS类封装
● ub 元素采用弹性BOX布局
● ub-rev 子元素反序排列
● ub-con 在子元素中加入一个容器,用于避免内容引起子元素大小变化。
对应CSS代码为position:absolute;width:100%;height:100%;
● ub-ac、ub-ae 子元素垂直居中对齐和尾对齐
● ub-pc、ub-pe、ub-pj 子元素水平居中对齐、尾对齐和两端对齐
● ub-ver 子元素纵向排列
● ub-f1 ub-f2 ub-f3 ub-f4 子元素占用区域份数
通过上述类,我们可以完成各种各样的排版布局,极大地降低学习难度和元素排版复杂度,使代码更加简练。
3、2UI2.0框架开发指南
3.1 基石 (UI的分辨率适配)
通过这种方式,我们可以保证,同样代码的界面,在不同分辨率下都能够保持最贴近用户的交互效果。
在UI1.0中,我们在HTML文件中引用ui-media.css,即可处理当前常见分辨率的适配。但是由于各手机平台不同,和各种新分辨率手机的问世,都对适配工作提出了更高的要求。
UI2.0中,我们在中间件中为不同屏幕密度(单位尺寸中可显示的点数),默认定义好了字体,开发者不再需要在代码中引入ui-media.css文件,即使有新的分辨率手机问世,也会自动适配。目前参照Andorid屏幕密度划分为低密度、普通密度、高密度、超高密度,分别定义字体为14px 16px 24px 32px。
3.2 骨架(元素布局与定位)
主干
主干可以认为是整个页面的整体框架布局
![](http://doc.appcan.cn/images/015.jpg)
![](http://doc.appcan.cn/images/016.png)
HEAD部分:
<head>
<title></title>6
<meta charset="utf-8">
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"<
<link rel="stylesheet" href="css/ui-base.css">
<link rel="stylesheet" href="css/ui-box.css">
<link rel="stylesheet" href="css/ui-color.css">
<link rel="stylesheet" href="css/ui-res.css">
<script src="js/zy_control.js">
</script<
<script src="js/zy_click.js">
</script>
</head>
BODY部分
<body class="um-vp c-wh" ontouchstart>
<div id="page_0" class="up ub ub-ver" tabindex="0">
<!--header开始-->
<div id="header" class="uh c-org c-m1 t-wh">
<h1 class="ut ulev0 ut-s tx-c" tabindex="0">AppCan</h1>
</div>
<!--header结束--> <!--content开始-->
<div id="content" class="ub-f1 tx-l t-bla ub-img6 res10">
</div>
<!--content结束--> <!--footer开始-->
<div id="footer" class="uf c-m2 c-bla t-wh">
<h1 class="ut ulev-2 tx-c" tabindex="0">(c) Copyright 3G2WIN and others 2011.
<br>
All rights reserved. </h1>
</div>
<!--footer结束-->
</div>
</body>
header和footer部分是一个DIV,是一个定高的区域(通过内容撑开)。content是一个弹性区域,它会占满page_0中除了header和footer外的区域。如果header和footer的高度变化,content的高度也会随之变化。 但是这种布局当内容区域有内容时会引起整个content的高度撑高,由于大部分移动终端都不支持DIV的内部区域滚动,这回造成整个页面能够被拖动,这是与我们要求不符的。我们通过SCRIPT区域的代码来处理这个问题。
SCRIPT部分:
<script>
zy_init();
window.uexOnload = function(type){
if (!type) {
zy_con("content", "index_content.html", 0, $$("header").offsetHeight);
}
window.onorientatiοnchange=window.οnresize=function()
{
zy_resize("content",0,$$("header").offsetHeight);
}
}
</script>
window.uexOnload事件用于在AppCan中间件扩展对象加载完成后调用。在这个函数里,我们调用了封装在 zy_control.js里的zy_con函数创建了一个浮动VIEW。这个View与content的区域保持同样的大小,位置也与content区域的位置保持相同。这个View显示的内容来自于index_content.html页面。也就是说,我们的index.html页面中content区域其实并不包含内容,它只起到一个定位的作用,为浮动View提供定位支持。
window.onorientatiοnchange=window.onresize这行代码为iOS和Andorid平台的屏幕旋转事件指定了回调函数,当发生屏幕旋转时,会调用这个函数,此时我们调用封装的zy_resize接口参照content区域的新的高宽位置重新定位了浮动窗口。
更方便的是,开发者可以为content区域开发不同的content页面,可以根据的操作随时使用zy_con接口变更content区域的页面内容来实现不同的功能。例如可以配合下方的导航条控实现功能切换。
![](http://doc.appcan.cn/images/017.png)
AppCan UI2.0框架支持浮动窗口的弹动效果,开发者可以很方便的实现弹动效果,在index_content.html中我们已经默认提供了范例代码。接着我们看一下实际的内容区域网页index_content.html。这个页面与index.html一样同样分为三个部分HEAD、BODY、SCRIPT。HEAD部分与index.html的HEAD部分一样没什么区别。BODY部分开发者可以根据需求添加列表、表单、地图等功能实现。SCRIPT部分的代码我们看一下:
<script>
zy_init();
window.uexOnload=function(type)
{
if(!type){
uexWindow.setBounce("1");
uexWindow.showBounceView("0","#FFF","0");
uexWindow.showBounceView("1","#FFF","0");
}
}
</script>
旁支
在完成页面后,我们需要对页面中的元素进行布局。使用弹性盒子,将使这个布局工作的难度降低很多。我们定一个目标,如下图
![](http://doc.appcan.cn/images/018.png)
![](http://doc.appcan.cn/images/019.png)
■ 图片子区域
● 右侧文字区域
■ 文字正文区域
■ 文章属性区域
我们在index_content.html种进行布局,代码如下
效果:
![](http://doc.appcan.cn/images/020.png)
<div οnmοusedοwn="zy_touch('btn-act')" class="ubb ub b-gra t-bla lis">
<div class="lis-th ub-img im">
<div class="ub-f1 ub ub-ver">
<div class="ulev1"><标题名>
<div class="ulev-1 umh4 t-gra">文本说明</div>
<div class="ub ub-ac t-gra ulev-2">
<div class="umh2 umw2 ub-img " style="background-image:url(css/img/icon1.png);">
<div class="ub-f1">收藏数</div>
<div class="umh2 umw2 ub-img " style="background-image:url(css/img/icon2.png);">
<div class="ub-f1"> 评论数</div>
</div>
</div>
</div>
这个例子只是一个简单的布局应用范例,通过这个例子来展示,AppCan UI2.0在布局页面时的简便性。
3.3 皮肤-元素的美化
![](http://doc.appcan.cn/images/021.png)
▶ 圆角类别: uc-{类型}[类型] [类别]
uc-tl, uc-tr, uc-bl, uc-br , uc-t, uc-b, uc-r , uc-l, uc-a, uc-n, uc-tl1, uc-tr1, uc-bl1, uc-br1, uc-t1, uc-b1, uc-r1, uc-l1, uc-a1, uc-a2, uc-a3
▶ 阴影类别: us [类别]和us-i [类别]
us,us1,us-i
▶ 比例类别:ulev[类别](由于元素的控制主要通过em来进行相对控制,ulev可以对默认比率进行放大缩小)
ulev2,ulev1,ulev0,ulev-1,ulev-2
▶ 浮动类别: ufl和ufr
▶ 限宽类别: ulim
▶ 单行类别: uinl
▶ 边距类别: uinn[类别]
uinn,uinn1,uinn2,uinn3,uinn4
▶ 最小高宽类别: um{w或h}[类别]
umh1,umh2,umh3,umh4,umh5,umh6,umw1,umw2,umw3
▶ 文字对齐类别:tx-{类型}
tx-l,tx-r,tx-c
▶ 文字缩略类别:ut-s
▶ 边框类别:ub{类型}[类别]
ubt,ubb,ubr,ubl,uba,uba1,uba2
▶ 隐藏类别:uhide
▶ 间隔类别:umar-{类型}
umar-b
色彩控制
UI2.0框架对元素的色彩划分为边框色、文字色、背景底色和背景遮盖层
▶ 背景遮盖类别: c-m{类别}
c-m1,c-m2,c-m3,c-m4,c-m5,c-m6,c-m7
▶ 背景底色类别: c-{色彩}[类别]
c-blu,c-blu1, c-blu2, c-blu3, c-blu4,c-wh, c-bla,c-gra,c-gra1,c-gra2,c-gre,c-red,c-yel
▶ 文字色类别:t-{色彩}[类别]
t-bla,t-wh,t-gra,t-blu
▶ 边框色类别:b-{色彩}[类别]
b-bla,b-wh,b-gra,b-gra1,b-blu
资源控制
UI2.0框架一些常用图片资源进行了定义。例如搜索图标等。
▶ 资源类别:res{类别}
res1,res2,res3,res4,res5,res6,res7,res8,res9,res10
AppCan UI2.0框架对一个元素的基础属性进行了拆分整理,通过不同的组合来定制元素效果,同时这个方案也是一种规则,开发者可以根据具体的实际情况在对应的类别中扩展自己需要的特效。遵循这个规则可以提高代码的可重复利用率和维护管理效率,避免团队开发中由于各种自定义类别混乱定义引起的UI适配和维护问题。同时使用UI2.0框架构建的控件,代码量将会极大地减少。下面一节我们将对各种常用在应用中的控件的实现来使大家了解UI2.0在UI实现上的巨大优势。
4、UI2.0中的控件
4.1 按钮
![](http://doc.appcan.cn/images/022.png)
![](http://doc.appcan.cn/images/023.png)
![](http://doc.appcan.cn/images/024.png)
![](http://doc.appcan.cn/images/025.png)
效果:
![](http://doc.appcan.cn/images/026.png)
<!--按钮开始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh">确定</div>
<!--按钮结束-->
最后我们通过uba1指定边框所有边都为2px宽,并通过b-bla设定边框色为黑色。到此就完成了一个按钮在不点击状态下的效果。相对于之前UI1.0中一个普通按钮需要一个DIV和两个SPAN的嵌套要简化了2/3的代码,层次也减低到一层。现在我们为这按钮加上点击效果。按照标准CSS3来说,只需要使用伪类:active来设定一个类即可完成鼠标按下弹起的效果变换, 但很遗憾,在Andorid平台,这个效果大部分手机支持的都有问题。对于iOS平台这个属性是支持的,但是如果想使这个伪类有效,则必须在代码中加入ontouchstart,才能够激活这个伪类。为了解决这个跨平台问题,我们提供了zy_touch接口,通过这个接口,它可以完成点击效果的处理。
这段代码中,我们加入了ontouchstart="zy_touch('btn-act')",zy_touch是封装在 zy_control.js中的扩展函数,btn-act是我们预定义的一个通用控件点击凹陷效果类。通过这个函数,我们构建了一个点击监听类zyClick(如果使用zy_touch还需要引用 zy_click.js),他会监听触摸屏事件,来控制为按键增加和去除点击效果,同时可以判断是否为点击操作,如果判定成功,会直接调用参数中的回调函数来达到onclick事件的效果,可以解决手机浏览器中onclick不灵敏的问题。同时zy_touch还支持直接调用HTML代码中的onclick属性实现点击效果。我们调整代码
代码:
<!--按钮开始-->
<div ontouchstart="zy_touch('btn-act')" οnclick="alert(1)" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh">确定</div>
<!--按钮结束-->
如果希望在模拟器上看到效果,可以替换ontouchstart为onmousedown。虽然手机中也支持onmousedown事件但是他的效果和时序和touch事件有差别,因此我们在手机中运行的时候还是要替换回ontouchstart。
上面的按钮是使用DIV实现的,而DIV默认是一个块。因此会占满整个宽度。如果需要使按钮与其他控件在同行显示,我们需要为齐添加uinl类。
效果:
![](http://doc.appcan.cn/images/027.png)
<!--按钮开始-->
<div ontouchstart="zy_touch('btn-act')" οnclick="alert(1)" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh uinl">确定</div>
<!--按钮结束-->
效果如下:
![](http://doc.appcan.cn/images/028.png)
<!--按钮开始-->
<div ontouchstart="zy_touch('btn-act')"class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac">
<div class="ub-f1 ut-s">确定</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--按钮结束-->
<!--按钮开始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac ub-rev">
<div class="ub-f1 ut-s">确定</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--按钮结束-->
<!--按钮开始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac ub-ver">
<div class="ub-f1 ut-s">确定</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--按钮结束-->
4.2 容器
![](http://doc.appcan.cn/images/029.png)
![](http://doc.appcan.cn/images/030.png)
![](http://doc.appcan.cn/images/031.png)
<div id="content" class="uinn2 c-org1 ub-f1"></div>
![](http://doc.appcan.cn/images/032.png)
<!--块容器开始-->
<div class="ub ub-ver uba b-gra uc-a1 t-wh ">
<div class="ubb b-gra c-blu c-m1 uinn uc-t1">条目1</div>
<div class="ubb b-gra c-blu c-m1 uinn ">条目2</div>
<div class="c-blu c-m1 uinn uc-b1 ">条目3</div>
</div>
<!--块容器结束-->
![](http://doc.appcan.cn/images/033.png)
<!--块容器开始-->
<div class="ub ub-ver uba b-gra uc-a1 t-bla c-wh">
<div class="ubb b-gra uinn uc-t1">条目1</div>
<div class="uinn uc-b1 ">条目3</div>
</div>
<!--块容器结束-->
我们先通过IDE中的编辑框向导
![](http://doc.appcan.cn/images/034.png)
![](http://doc.appcan.cn/images/035.png)
<div class="ubb b-gra uinn uc-t1">
<!--文本开始-->
<div class="ub t-bla ulab"> <div class="uinn ulim">标签标签</div>
<div class="ub-f1 c-blu uba uc-a1 b-gra us-i uinput uinn4">
<input placeholder="hello" type="text" class="uc-a1">
</div>
</div><!--文本开始-->
</div>
![](http://doc.appcan.cn/images/036.png)
<div class="ubb b-gra uinn uc-t1">
<!--文本开始-->
<div class="ub t-bla ulab ub-ac"> <div class="ulim">用户名</div>
<div class="ub-f1 uinput uinn4">
<input placeholder="hello" type="text" class="uc-a1">
</div>
</div><!--文本开始-->
</div>
![](http://doc.appcan.cn/images/037.png)
下面我们再增加两个按钮。首先在编辑区域容器下方再构建一个横向排列容器。
![](http://doc.appcan.cn/images/038.png)
<div class="ub uba b-gra c-blu c-m1 t-wh uc-a1 ">
<div class="ubr b-gra ub-f1 uinn uc-l1">条目1</div>
<div class="ubr b-gra ub-f1 uinn ">条目2</div>
<div class="ub-f1 uinn uc-r1">条目3</div>
</div>
</div>
清理后的代码如下
![](http://doc.appcan.cn/images/039.png)
<!--块容器开始-->
<div class="ub ">
<div class="ub-f1 uinn">条目1</div>
<div class="ub-f1 uinn">条目2</div>
</div>
</div>
<!--块容器结束-->
![](http://doc.appcan.cn/images/040.png)
<!--块容器开始-->
<div class="ub ">
<div class="ub-f1 uinn">
<!--按钮开始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba b-gra uinn5 c-wh c-m1 uc-a t-bla">确定</div>
<!--按钮结束-->
</div>
<div class="ub-f1 uinn">
<!--按钮开始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba b-org uinn5 c-org c-m1 uc-a t-wh">确定</div>
<!--按钮结束-->
</div>
</div>
<!--块容器结束-->
4.3 编辑框
![](http://doc.appcan.cn/images/ui_img1.jpg)
搜索框
一般搜索框常会用在标题下面,我们对index.html页面做一下调整,在标题栏和内容区域之间插入一个搜索框。代码如下
<!--文本开始-->
<form id="search" οnsubmit="alert('submit')">
<div class="t-bla ub uba uc-a b-gra us-i uinput ub-rev uinn4">
<div class="res6 umw1 ub-img ">
</div>
<div class="ub-f1 uinn1">
<input placeholder="search" type="text" class="" style="background:none;">
</div>
</div>
</form>
<!--文本结束-->
zy_con("content", "index_content.html", 0, $$("header").offsetHeight+$$("search").offsetHeight);
zy_resize("content",0,$$("header").offsetHeight+$$("search").offsetHeight);
目前搜索框两边的圆角并没有使其显示成半圆形,我们只需要调整一下搜索框容器的uc-a类为uc-a2即可,uc-a2是一个更大的圆角。最终效果如下
![](http://doc.appcan.cn/images/ui_img2.jpg)
接下来我们在index_content.html中添加一个输入域。通过编辑框向导创建一个带标签的输入域。
![](http://doc.appcan.cn/images/ui_img3.jpg)
![](http://doc.appcan.cn/images/ui_img4.jpg)
<!--文本开始-->
<div class="ub t-bla ulab">
<div class="uinn ulim">
标签标签
</div>
<div class="ub-f1 uba uc-a1 b-gra us-i uinput uinn4 ub ub-ver">
<textarea placeholder="hello" name="area1" class="uc-a1 ub-f1"></textarea>
</div>
</div>
<!--文本结束-->
![](http://doc.appcan.cn/images/ui_img5.jpg)
<!--文本开始-->
<div class="ub t-bla ulab ub-ver">
<div class="uinn ulim">
标签标签
</div>
<div class="ub-f1 uba uc-a1 b-gra us-i uinput uinn4 ub ub-ver umh6">
<textarea placeholder="hello" name="area1" class="uc-a1 ub-f1"></textarea>
</div>
</div>
我们对上面的代码进行一个分析。
首先最外侧是一个容器,这个容器采用弹性盒子架构(ub),定义了默认文本色(t-bla),由于有标签,所以我们加入了标签类(ulab),他主要控制标签和编辑区域的横向间距,如果纵向排列这个类可以删除。容器中有两个子元素,一个是标签一个是子容器。标签元素使用uinn为齐添加内边距,使用ulim来限制其长度。子容器用于定义编辑框的效果即阴影(us-i)、高度(umh6)、边框(b-gra、uba)。为了使输入域与边框间留下空隙,我们为子容器加上内边距(uinn4),uinput定义textarea元素的效果,ub定义此子容器依然是一个弹性盒子。由于输入域在适配中的特殊性,我们为子容器定义ub-ver,要求妻子元素纵向排列。接着我们为textarea指定ub-f1,使其撑满整个容器内边距内区域。最后的代码看附件 Demo011范例。
4.4 下拉列表控件
![](http://doc.appcan.cn/images/ui_img6.jpg)
![](http://doc.appcan.cn/images/ui_img7.jpg)
效果:
![](http://doc.appcan.cn/images/ui_img8.jpg)
<!--下拉列表开始-->
<div class="ub t-bla">
<div class="uinn ulim">标签标签</div>
<div class="ub-f1 ub uba uc-a1 c-wh b-org us-i sel">
<div class="ub-f1 ut-s uinn ulev-1 tx-l">下拉列表</div>
<div class="ubl b-org c-red c-m2 umw2 ub ub-pc uc-r2 ub-ac">
<div class="ub-img umw1 umh1 res3"></div>
</div>
<select name="sel0" selectedindex="0" id="sel0" οnchange="zy_slectmenu(this.id)">
<option>item1</option>
<option>item2</option>
<option>item3</option>
<option>item4</option>
</select>
</div>
</div>
■文字区域-用于显示选中的条目内容
■按钮区域-是一个容器包含一个下箭头的图标。这个图标通过弹性盒子进行居中显示
■Select控件-是一个与整个下拉列表容器等高宽的透明控件,这样用户看到的是我们的文字区域和按钮区域,但实际点击时,点击的是系统Select控件。在select控件中我们通过zy_selectmenu接口截取用户选中的条目,修改文字区域内容
上述控件中,不管是最外面的容器还是子容器,我们都使用的是弹性盒子模型。
4.5 导航栏
![](http://doc.appcan.cn/images/ui_img9.jpg)
效果:
![](http://doc.appcan.cn/images/ui_img10.jpg)
<!--iPhone导航条开始-->
<div class="ub c-bla c-m1 tab t-wh">
<input class="uhide" type="radio" name="tabSwitch" checked="true">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-info"></div><div class="uinn ulev-2 tx-c">新闻</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-home"></div><div class="uinn ulev-2 tx-c">新闻</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-set"></div><div class="uinn ulev-2 tx-c">新闻</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-shop"></div><div class="uinn ulev-2 tx-c">新闻</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-talk"></div><div class="uinn ulev-2 tx-c">新闻</div></div>
</div>
■radiobox控件-此控件为隐藏控件,并不现实(uhide),他的作用是通过和其他具有同样name属性的radiobox控件组合使用,来实现条目的单项选择,配合后面子元素的CSS类属性实现选中和未选中效果。
■子容器-用于容纳每一个条目的子元素。同时负责显示选中和未选中状态(tab-act)。我们看一下ui-tab.css中tab-act的定义。
input[type="radio"]:checked + div.tab-act
{
background-color:rgba(255,255,255,0.1) !important;
border-radius:0.3em;
border: 0px;
background-image: none;
}
■图片元素-用于显示每一个条目得图片(tp-info)。由于每个条目的图片不同,需要为每个图片元素设定图片资源。目前我们在ui-tab.css中预置了六组图片资源类,用户可以根据需求替换相应的图片资源。每一组图片资源分选中状态和为选中状态,我们以tp-info为例进行分析。
input[type="radio"] + div>div.tp-info{
background: url(res-apple/info.png) 50% 50% no-repeat;
}
input[type="radio"]:checked + div>div.tp-info{
background: url(res-apple/info-act.png) 50% 50% no-repeat;
}
导航栏并不一定都是这种显示效果,我们修改一下代码实现以下另一种效果。
![](http://doc.appcan.cn/images/ui_img11.jpg)
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="uinn3 tx-c">新闻</div><div class="uinn ulev-1 tx-c">news</div></div>
上面展示的良种效果会有些问题,我们可以看到每一个子容器都是通过ub-f1进行等分的,但在文章最开始我们介绍时提到过,如果自容器中的内容并不等长时,浏览器会动态的调整每个字元素的宽度即时齐都是相同的flex属性。如果确实出现了文字不等长的情况,我们该如何调整呢?我们调整一下Demo014范例的代码 Demo015范例。 <div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">早间新闻</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>
导航条的目的是为了配合页面的切换。那么下面我们演示一下如何通过导航条快速实现页面切换。我们目前已经有了一个index.html和一个index_content.html,那么我们为index.html页面在建立一个内容页面。复制index_content.html,改名为msg_content.html。这个时候我们就有了两个内容页面。我们在script区域添加两个函数
function loadmsgcontent(){
zy_con("content", "msg_content.html", 0, $$("header").offsetHeight);
}
function loadindexcontent(){
zy_con("content", "index_content.html", 0, $$("header").offsetHeight);
}
<div ontouchstart="zy_touch('',zy_for)" οnclick="loadindexcontent()" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">早间新闻</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>
<div ontouchstart="zy_touch('',zy_for)" οnclick="loadmsgcontent()" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">新闻</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>
4.6 单选框和复选框
![](http://doc.appcan.cn/images/ui_img12.jpg)
![](http://doc.appcan.cn/images/ui_img13.jpg)
![](http://doc.appcan.cn/images/ui_img15.jpg)
<!--复选框开始-->
<input type="checkbox" name="che1" class="uhide" checked="checked" value="">
<div οnclick="zy_for(event)" ontouchstart="zy_touch('btn-act')" class="ub uc-a1 uba c-gra c-m2 b-gra t-bla uinn5 ">
<div class="ub-f1 ut-s tx-l" >item</div>
<div class="che-icon ub-img umw1"></div>
</div>
<!--复选框结束-->
input[type=checkbox]+div>div.che-icon {
background-color: transparent;
background-image: url(images/icons-18-white_39.png);
}
input[type=checkbox]:checked+div>div.che-icon {
background-color: transparent;
background-image: url(images/icons-18-white_37.png);
}
复选框还有一种变形,我们看看如下范例 Demo017范例,通过向导选择
![](http://doc.appcan.cn/images/ui_img16.jpg)
![](http://doc.appcan.cn/images/ui_img17.jpg)
<!--复选框开始-->
<div class="ub uc-a1 t-bla c-gra c-m2 uba b-gra tx-c">
<input type="checkbox" name="che1" class="uhide" value="">
<div οnclick="zy_for(event)" class="uinn5 ubr b-gra uc-l1 ub-f1 che">item</div>
<input type="checkbox" name="che2" class="uhide" value="">
<div οnclick="zy_for(event)" class="uinn5 ubr b-gra ub-f1 che">item</div>
<input type="checkbox" name="che3" class="uhide" value="">
<div οnclick="zy_for(event)" class="uinn5 uc-r1 ub-f1 che">item</div>
</div>
<!--复选框结束-->
input[type=checkbox]:checked+div.che {
box-shadow:inset 0 1px 2px rgba(0,0,0,0.6);
}
对于纵向排列的复选框分组就不作介绍了,大家可以自己通过模板建立一个,研究一下代码。它其实就是一个容器里放了多个单条复选框而已。
单选框和复选框基本代码和设计都是一致的只是单选框的隐藏input标签类型为radio而已。大家可以研究一下ui-input.css中的类定义
4.7 列表控件
![](http://doc.appcan.cn/images/ui_img18.jpg)
![](http://doc.appcan.cn/images/ui_img19.jpg)
效果:
![](http://doc.appcan.cn/images/ui_img20.jpg)
<!--列表开始-->
<div class="uba b-gra c-wh us uc-a ">
<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">设置</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
<div ontouchstart="zy_touch('btn-act')" class=" ub ubb b-gra c-m2 t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">设置</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
<div ontouchstart="zy_touch('btn-act')" class="uc-b c-m2 ub t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">设置</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
</div>
<!--列表结束-->
<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">设置</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
这是一个容器,由于是第一行,所以他的圆角要和外面容器的圆角保持匹配,因此我们为其设定圆角(uc-t),这个容器和下一行需要一条分割线,我们设定这个子容器右下边界(ubb),边界色彩为(b-gra),这个条目有一点简便效果,我们采用的是(c-m2)由于其位于容器内,这个遮盖层会和父容器背景色进行组合。这个子容器包含多个元素,这些元素也是以弹性盒子模型进行排版(ub),文字色彩定义为黑色(t-bla),由于容器中的子元素高低不定,因此我们要求其子元素中线对其(ub-ac)。最后是设定列表条目的默认效果(lis 建立了内边距)。<div class="lis-icon ub-img im"></div>
这是容器中的第一个元素,它是一个小图片,我们设定了这个图片的高宽(lis-icon),同时设定了这个图片是(im),图片的展示参数通过(ub-img)来设定。 备注:默认工程中的ui-img.css定义了我们范例中的范例资源图片,而ui-res.css是我们控件需要的资源图片。
<div class="ub-f1 ut-s">设置</div>
这一行设定了一个弹性区域,他会撑满真个容器的空闲区域(ub-f1),当文字长度超过可容纳区域后,进行缩略(ut-s)。<div class="tx-r t-blu ulev-1">Old Phone</div>
这一行定义了一个文字去,这个文字区的大小会根据文字长度进行调整。我们通过ulev-1对此地的文字进行缩小显示。并通过t-blu设定其颜色为兰色。<div class="res8 lis-sw ub-img"></div>
最后这个元素是一个小箭头图标。lis-sw定义了他的大小,res8指定了所用的资源,ub-img定义了图片的展示方式。通过这部分解析我们看到一个列表其实也是由最基本的容器和元素组合而成。通过弹性盒子模型,真个列表的排布会非常简洁明了。
4.8 开关按钮
![](http://doc.appcan.cn/images/ui_img21.jpg)
![](http://doc.appcan.cn/images/ui_img22.jpg)
<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">设置</div>
<!--开关按钮开始-->
<input class="uhide" type="checkbox" checked="true" >
<div class="uba b-gra swi swi-bg uc-a1" οnclick="zy_for(event)"></div>
<!--开关按钮结束-->
</div>
![](http://doc.appcan.cn/images/ui_img23.jpg)
input[type=checkbox]:checked + div.swi{
background-position:-0.1em;
}
input[type=checkbox] + div.swi
{
background-position:-4.01em
}
通过上面的讲解,我们展示了UI2.0的框架设计思想。并通过对我们预置组件代码的分析,使大家对如何使用UI2.0框架调整界面有了一个基本的认识。我们总结一下我们公司开发人员的UI设计规则
1. 制作前先考虑好如何组织页面,需要如何布局,在什么地方需要几个容器来进行排版。然后构建架子,使用默认效果类进行排版定位和美化
2. 如果需要使用颜色,请在ui-color.css中根据文本、背景、遮盖、边框等分别扩展自己的类定义
3. 如果需要调整圆角、边距等附加属性请在ui-base.css中进行添加。
4. 如果需要资源,请在ui-res.css中进行扩展
5. 如果需要布局,请在ui-box.css中进行调整
6. 所有调整要遵循默认的命名规则。
遵守这些规则可以使你的代码更容易被其他人阅读,代码复用和调整将会更加简单