从零开始用htmlayout/sciter写漂亮ui界面之仿瑜伽管理界面
如题:
参考之前别人发的瑜伽那个htmlayout的代码 , 一步一步从零开始手打出来, 看看一个完整的hL界面是怎么写出来的.
当然, 过程中不会完全和原来的代码一样, 中间如果有其他的想法或者简单方式, 我都会去试一下, 力争最简化实现同样界面.
示例的工程源码如下: (只要下面帖子里更新了,就会更新这个分享的zip文件)
链接:https://pan.baidu.com/s/1BgQWbAmLsOqQlSA4YMLSIA
提取码:f9zl
新建mainform界面
导入htmlayout库
工程中添加html目录和img子目录
打开工程文件夹, 在html目录里新建main.html和main.css两个文件
同步html目录
mainform.aardio代码如下
import win.ui; /*DSG{{*/ mainForm = win.form(text="aardio工程7";right=959;bottom=591) mainForm.add() /*}}*/ import web.layout; import web.layout.behavior.windowCommand; var wb = web.layout(mainForm); wb.go("\html\main.html"); mainForm.show(); return win.loopMessage();
双击main.html用editplus打开, 输入基本的代码如下
<html> <body> hello aar </body> </html>
此时, 运行工程, 可以看到界面输出
说明基本框架创建完成.
下面正式开始:
首先把html和css文件关联起来, html里用link语句
<html> <link href="main.css" rel="stylesheet" type="text/css"/> <body> hello aardio123456 </body> </html>
如果记不住那么长的link语句, 那么还有另外一种方式
<style> @import "main.css"; </style>
同样能引用到main.css样式到文件中
同时, 把准备好的一些图片放入到img目录里
我们在css里设置body节点的属性
设置整个body铺满界面, 外边距为0
设置body的背景图片为预设好的skin.png
body{ margin:0px; background-image:url(img/skin.png); }
我们看到这个图片比界面小, 所以它连续平铺来铺满了整个界面, 但是一般界面上面不会这么做, 一般都是用九宫格拼图
那么需要增加 背景模式为九宫格
background-repeat:expand stretch-left stretch-middle stretch-right; background-position:0 0 0 0;
可以看到此时一张图铺满了界面, 但是貌似整个图片是被拉伸的, 像素改变导致模糊了,这时候需要改变position属性里面的值, 来保证图片中的树芽部分是清晰的
改为(上右下左)
background-position:280 2 2 680;
大概是这样切的
这里就需要去理解了九宫格再去看这张图片, 我们拉伸了left , middle , right的九宫格部分, 而四个角我们是不变的, 无论你怎么去调整界面大小, 四个顶点格图片不变.如下动态演示
原来界面中有个边框图片, 那么我们也弄到界面上去, 我这里不用它原来的方法, 我加入属性到body里去
body{ margin:0px; background-image:url(img/skin.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position:280 2 2 680; foreground-image:url(img/border.png); }
界面变成了这副样子... , 就和背景图片一样, 设置为九宫格模式
body{ margin:0px; background-image:url(img/skin.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position:280 2 2 680; foreground-image:url(img/border.png); foreground-repeat:expand stretch-left stretch-middle stretch-right; foreground-position:5 5 5 5; }
此时可以看到界面有边框了
增加界面头部拖动功能
首先, 在html中添加
<div #header> </div>
以上,增加了id为header的节点, 在css中设置这个节点的属性
#header{ background-color:red; width:100px; height:30px; }
以上增加这个节点的背景色为红色, 这样更利于观察, 并设置高度和宽度, 没有高和宽这个节点是显示不出来的.
现在设置它的宽度100%
width:100%;
红色充满了界面, 而且调整界面大小也不影响
设置这个节点的behavior行为为windowCommand窗体消息
#header{ background-color:red; width:100%; height:30px; behavior:windowCommand; }
在html中定义这个节点的功能
<html> <link href="main.css" rel="stylesheet" type="text/css"/> <body> <div #header command="window-caption"> </div> </body> </html>
window-caption是aardio内置的htmlayout消息封装, 直接用即可
此时可以看到界面可以被拖动了
下面在顶部增加窗体的最小化和关闭按钮
html中增加这三个功能的div
<html> <link href="main.css" rel="stylesheet" type="text/css"/> <body> <div #header command="window-caption"> <div #skin /> <div #btn-min /> <div #btn-close /> </div> </body> </html>
主要是在css里定义他们的分布和属性
#skin{ background-image:url(img/btn_Skin_normal.png); width:28px; height:20px; }
看到上面的小衣服了, 再接再厉, 继续添加
#skin{ background-image:url(img/btn_Skin_normal.png); width:28px; height:20px; } #btn-min{ background-image:url(img/btn_mini_normal.png); width:28px; height:19px; } #btn-close{ background-image:url(img/btn_close_normal.png); width:39px; height:19px; }
成这样了..... , 看了css的文章知道, div是block(块) , 会独占一行, 所以紧接着的都会自动往下走, 那么就需要设置flow属性了,在它们的父节点header里添加横向浮动
#header{ //background-color:red; width:100%; height:30px; flow:horizontal; behavior:windowCommand; }
横过来了, 但是都挤在左边, 怎么弄到右边去?
很遗憾, htmlayout没有这样的flow属性, 那么怎么实现这样的功能?
可以反其道而行之, 我们假设有四个按键, 第一个按键占比较大的宽度, 这样就把其他的按钮给挤到右边去了.
验证一下:
html中增加一个空白按钮space
<html> <link href="main.css" rel="stylesheet" type="text/css"/> <body> <div #header command="window-caption"> <div #space /> <div #skin /> <div #btn-min /> <div #btn-close /> </div> </body> </html>
在css中定义它无限宽(占去其他按钮剩下来的所有空间), 这里要用到 %% 功能
#space{ width:100%%; height:20px; }
挤过去了, 放大缩小界面也不会有影响
给按钮增加鼠标的各种状态:
#skin{ background-image:url(img/btn_Skin_normal.png); width:28px; height:20px; margin:-1px; } #skin:hover{ background-image:url(img/btn_Skin_highlight.png); } #skin:active{ background-image:url(img/btn_Skin_down.png); }
上面为什么margin:-1, 这个图片比其他的大了一个像素,减去之后高度才刚刚好.
依葫芦画瓢, 增加其他几个按钮的状态
<div #btn-min command="window-min"/> <div #btn-close command="window-close"/>
由于在它们的父节点中已经增加了behavior:windowCommand; 所以, 它们css中就没必要再去写了,直接再html中写入功能即可.
皮肤更改功能界面:
参考主界面的html和css,稍作修改即可.如下:
<html> <link href="skin.css" rel="stylesheet" type="text/css"/> <body> <div #header command="window-caption"> <div #space>更改外观</div> <div #btn-close command="window-close"/> </div> </body> </html>
body{ margin:0px; background-image:url(img/001/skin.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position:280 2 2 680; foreground-image:url(img/border.png); foreground-repeat:expand stretch-left stretch-middle stretch-right; foreground-position:5 5 5 5; } #header{ //background-color:red; width:100%; height:70px; flow:horizontal; behavior:windowCommand; } #space{ width:100%%; height:20px; font-weight:bold; font-size:14px; color:white; padding:5 0 0 8; } #btn-close{ background-image:url(img/btn_close_normal.png); width:39px; height:19px; } #btn-close:hover{ background-image:url(img/btn_close_highlight.png); } #btn-close:active{ background-image:url(img/btn_close_down.png); }
增加一个蒙版main:
<html> <link href="skin.css" rel="stylesheet" type="text/css"/> <body> <div #header command="window-caption"> <div #space>更改外观</div> <div #btn-close command="window-close"/> </div> <div #main> </div> </body> </html>
修改这个蒙版的css属性
#main{ background-color:rgba(255,255,255,0.6); margin:0 -5 -5 -5; padding:0 5 5 5; width:100%%; height:100%%; }
在main节点中增加两个区域, 一个用来显示皮肤框,, 一个用来作为底部按键
先来设置下皮肤显示区
我们增加mainarea节点和main-bottom节点
<html> <link href="skin.css" rel="stylesheet" type="text/css"/> <body> <div #header command="window-caption"> <div #space>更改外观</div> <div #btn-close command="window-close"/> </div> <div #main> <div #mainarea> </div> <div #main-bottom> </div> </div> </body> </html>
定义一下css样式
#mainarea{ background-color:rgba(0,66,33,0.3);//随便写的,便于观察 margin:0 1 1 1; width:100%%; height:100%%; } #main-bottom{ background-color:rgba(88,88,88,0.3);//随便写的,便于观察 margin:0 5 0 5; width:100%%; height:35; }
预设底部是35高的一个底部框, 上面剩下的都是显示区域, 效果如下:
下面在mainarea那块区域内添加皮肤列表.
<div #mainarea> <div #skin-area> </div> </div>
并设置css为
#skin-area{ background-color:white; margin:7; padding:1 1 1 1; width:100%%; height:100%%; }
下面就是往皮肤区放入内容了
在html的skin-area区域添加内容
<div #skin-area> <img src="img\001\preview.png"/> </div>
再接再厉, 继续添加看看
<div #skin-area> <img src="img\001\preview.png"/> <img src="img\002\preview.png"/> <img src="img\003\preview.png"/> <img src="img\004\preview.png"/> <img src="img\005\preview.png"/> <img src="img\006\preview.png"/> <img src="img\007\preview.png"/> <img src="img\008\preview.png"/> <img src="img\009\preview.png"/> <img src="img\010\preview.png"/> </div>
变成了这副样子,滚动条也好丑, 为了让滚动条显示只显示在skin-area区域, 而不是整个窗口,那么需要在skin-area的父节点mainarea设置内容超出边界则隐藏滚动条
#mainarea{ background-color:rgba(0,66,33,0.3); margin:0 1 1 1; width:100%%; height:100%%; overflow:hidden; }
滚动条消失了, 可是,图片列表显示也很奇怪, 我们需要它横向显示, 并且在超出边界的时候换行并能显示滚动条,htmlayout的flow属性里面刚好有这个模式,
#skin-area{ background-color:white; margin:7; padding:1 1 1 1; width:100%%; height:100%%; flow:h-flow; overflow-y:auto; }
测试了overflow的其他几个属性, 发现hidden-scroll和scroll-indicator都没效果,
(经测试换成sciter是支持的,估计htmlayout还不支持)
目前先用auto吧, 就是丑了点
为了让滚动条好看一点,细一点, 那么我们可以自定义垂直滚动条, 参考htmlayout的手册示例,
我们在css中添加如下代码:
@set small-v-scrollbar { .slider { background-color: rgba(114,150,60,0.7); } .base { width: 3px; } /* explicit declaration of scrollbar width */ } * { vertical-scrollbar: small-v-scrollbar; } /* all scrollable elements will have our small scrollbar now */
上面就是自定义的简短的代码, 更详细的介绍还是参考官方的文档,
上面图片间隔好大, 感觉不自然, 好丑, 经过测试, 在css中直接定义
img { width:120px; height:120px; padding:1; }
并不能达到效果,
这时候参考这个程序之前的代码, 需要用div再次嵌套下. 我们把每个img都放入到div中去, 然后去操作div
<div #skin-area> <div .listimg> <img src="img\001\preview.png"/> </div> <div .listimg> <img src="img\002\preview.png"/> </div> <div .listimg> <img src="img\003\preview.png"/> </div> <div .listimg> <img src="img\004\preview.png"/> </div> <div .listimg> <img src="img\005\preview.png"/> </div> <div .listimg> <img src="img\006\preview.png"/> </div> <div .listimg> <img src="img\007\preview.png"/> </div> <div .listimg> <img src="img\008\preview.png"/> </div> <div .listimg> <img src="img\009\preview.png"/> </div> <div .listimg> <img src="img\010\preview.png"/> </div> </div>
看到上面的 .listimg 了吗? 这里要用圆点 . , 圆点的意思是这个属性可以被重复使用, 就是名字可以重复, 相同名字的节点属性一致, 而我们上面一直用的是# , #表示的是此名字是唯一的, 不能重复使用.
ok , 去css里面设置下属性
#skin-area{ background-color:white; margin:7; padding:1 1 1 0; width:100%%; height:100%%; flow:h-flow; overflow-y:auto; } .listimg{ width:120px; height:120px; padding:0 0 1 1; } img { max-width:120px; max-height:120px; }
以上, 设置内边距的 底部和左边为1 ,其他是0, 因为我们的div是靠左靠上对齐的. 所以间距就刚刚好都是1了, 看起来整齐多了.
点击图片实现切换背景
为了能够动态切换背景图片, 需要把每个图片的div设置一个自定义的属性用来区分点击的是哪个图片.
html中修改, 增加了自定义的属性Lname,区分不同的节点
<div #skin-area> <div .listimg Lname="001"> <img src="img\001\preview.png"/> </div> <div .listimg Lname="002"> <img src="img\002\preview.png"/> </div> <div .listimg Lname="003"> <img src="img\003\preview.png"/> </div> <div .listimg Lname="004"> <img src="img\004\preview.png"/> </div> <div .listimg Lname="005"> <img src="img\005\preview.png"/> </div> <div .listimg Lname="006"> <img src="img\006\preview.png"/> </div> <div .listimg Lname="007"> <img src="img\007\preview.png"/> </div> <div .listimg Lname="008"> <img src="img\008\preview.png"/> </div> <div .listimg Lname="009"> <img src="img\009\preview.png"/> </div> <div .listimg Lname="010"> <img src="img\010\preview.png"/> </div> </div>
此时,我实验了用csss!里动态切换背景, 但是没有成功
.listimg{ width:120px; height:120px; padding:0 0 1 1; active-on!: $1(div.listimg:checked):checked = false , $1(body)::background-image = url("img/" + self.Lname + "/skin.png)", self:checked = true; } .listimg:checked{ outline:2px dotted blue -1px; }
貌似url()把里面的东西都看作是一个字符串, 没有变量这个概念 .......
当我把url内地址直接改成静态的img/002/skin.png , 就可以点击就切换,
目前不知道这种方式怎么去解决.....
于是 ,我改用另外一种方式, 定义一个behavior, 在aardio里对html进行修改
skin.aardio代码如下: 添加个名字为myselect的自定义行为
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=541;bottom=392;border="none") winform.add() /*}}*/ import web.layout; import web.layout.behavior.windowCommand; var wb = web.layout(winform,0xFFFF/*_HL_HANDLE_ALL*/); namespace web.layout.behavior.myselect { onMouseClick = function (ltTarget,ltOwner,x,y,ltMouseParams) { var cmd = ltTarget.Lname or ltOwner.Lname; var wbLayout = ltOwner.getLayout(); var ltEleBody = wbLayout.querySelector("body"); ltEleBody.style["background-image"]="url(img\"++cmd++"\skin.png)"; } } wb.go("\html\skin.html") winform.show(); win.loopMessage(); return winform;
并且在css中引用这个行为
.listimg{ width:120px; height:120px; padding:0 0 1 1; behavior:myselect; active-on!: $1(div.listimg:checked):checked = false , self:checked = true; }
曲线救国也实现了切换背景功能....
底部增加两个按键
html中增加
<div #main-bottom> <div .btn >确 认</div> <div .btn >退 出</div> </div>
css中增加横向浮动和垂直居中
#main-bottom{ //background-color:rgba(88,88,88,0.3); margin:0 5 0 5; width:100%%; height:35; flow:horizontal; vertical-align:middle; }
再定义按钮的皮肤
.btn{ width:69px; height:22px; background-image:url(img/login_btn.png); background-repeat:no-repeat; text-align:center; vertical-align:middle; } .btn:hover{ background-position: 0 0 0 -69; } .btn:active{ background-position: 0 0 0 -138; }
文本居中和垂直居中, 要不然会偏 , hover和active那里负号代表图片往前挪
这两个按钮太近了, 而且再左侧, 那么放右侧, 并拉开间距;
正如之前说的, 增加个空白div把它们挤到右边去
<div #main-bottom> <div #space/> <div .btn >确 认</div> <div .btn >退 出</div> </div>
css中.btn属性里增加外边距, 左侧设置为10px ,这样
.btn{ width:69px; height:22px; background-image:url(img/login_btn.png); background-repeat:no-repeat; text-align:center; vertical-align:middle; margin:0 0 0 10; }
再增加个关闭功能, .btn中添加行为
.btn{ behavior:windowCommand;
html里增加close功能
<div .btn command="window-close">确 认</div> <div .btn command="window-close">退 出</div>
搞定.
我们回到主界面中, 把刚刚的换肤界面绑定到主界面的皮肤按钮上
首先, 再mainform.aardio中增加一个自定义行为myshowskin
namespace web.layout.behavior.myShowSkin { onMouseClick = function (ltTarget,ltOwner,x,y,ltMouseParams) { var frmChild = ..mainForm.loadForm("\dlg\skin.aardio"); frmChild.show(); } }
意思是只要执行了这个行为, 那么就打开skin窗体.
我们还要绑定这个行为到css中, 要不然它自己也不知道在哪执行啊
#skin{ background-image:url(img/btn_Skin_normal.png); width:28px; height:20px; margin:-1px; behavior:myShowSkin; }
那么如果想要在skin界面点击换肤后, 主界面也换过来呢?
用publish来操作
在主界面中
subscribe("改变皮肤",function(flag){ var ltEleBody = wb.querySelector("body"); ltEleBody.style["background-image"]="url(img\"++flag++"\skin.png)"; } )
在skin界面publish
namespace web.layout.behavior.myselect { onMouseClick = function (ltTarget,ltOwner,x,y,ltMouseParams) { var cmd = ltTarget.Lname or ltOwner.Lname; var wbLayout = ltOwner.getLayout(); var ltEleBody = wbLayout.querySelector("body"); ltEleBody.style["background-image"]="url(img\"++cmd++"\skin.png)"; ..publish("改变皮肤",cmd) } }
主界面, tab导航栏:
html中增加工具栏和一些项目
<div #tabBar> <div .tab>首页</div> <div .tab>上课</div> <div .tab>管理</div> <div .tab>记录</div> </div>
#tabBar{ width:100%%; height:32px; background-color:red; margin:50 0 0 0; flow:horizontal; }
横向浮动, 上面预留50像素空间, 为了便于观察设置背景色红色
下面去定义tab的css属性
设置背景图片
设置div高度, 没高度看不出效果
九宫格拉伸左中右
微调下拉伸位置
.tab{ background-image:url(img\main_tabbtn_normal.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position: 1px 25px 1px 10px; height:32px; margin:0 -7 0 0; }
可以看出个大概效果了,
可以看到宽度太大了, 根据csss!的介绍, 可以用calc来计算适应宽度
.tab{ background-image:url(img\main_tabbtn_normal.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position: 1px 25px 1px 10px; height:32px; margin:0 -7 0 0; vertical-align:middle; padding:0 5 0 10; width: calc( max-intrinsic-width() + 25px ); }
增加交互效果
.tab:hover{ background-image:url(img\main_tab_highlight.png); } .tab:checked{ background-image:url(img\main_tab_check.png); font-weight:bold; }
参考之前的csss!时间写法, 把checked状态写好
.tab{ background-image:url(img\main_tabbtn_normal.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position: 1px 25px 1px 10px; height:32px; margin:0 -7 0 0; vertical-align:middle; padding:0 5 0 10; width: calc( max-intrinsic-width() + 25px ); active-on!: parent = self.parent(), parent.$1(.tab:checked):checked = false , self:checked = true; }
单击后, 该项即被checked
添加图片到tab中, 并增加默认选中项 checked
<div #tabBar> <div .tab checked><img src="img\home.png" />首页</div> <div .tab><img src="img\jilu.png" />上课记录</div> <div .tab><img src="img\manage.png" />管理人员</div> <div .tab><img src="img\xinde.png" />信息记录</div> </div>
然后设置img属性
.tab{ background-image:url(img\main_tabbtn_normal.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position: 1px 25px 1px 10px; height:32px; margin:0 -7 0 0; vertical-align:middle; padding:0 5 0 15; width: calc( max-intrinsic-width() + 25px ); active-on!: parent = self.parent(), parent.$1(.tab:checked):checked = false , self:checked = true; assigned!: parent = self.parent() , check_tab = parent.$1(.tab[checked]), check_tab:checked = true ; } .tab:hover{ background-image:url(img\main_tab_highlight.png); } .tab:checked{ background-image:url(img\main_tab_check.png); font-weight:bold; } .tab img { width:20px; height:20px; vertical-align:middle; margin:0 5 0 0; }
我把图片和文字间距放宽了一些, 看着舒服点
上面
assigned!:
是在html加载完成后执行的操作, 这里用来查找checked项目,选中它
html中增加tab页:
<div #tabArea> <div .page>首页----页面演示</div> <div .page>上课记录----页面演示</div> <div .page>管理人员----页面演示</div> <div .page>信息记录----页面演示</div> </div>
主要是对css的设置:
#tabArea{ height:100%%; width:100%%; background-image:url(img\for_back.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position: 80 12 50 12; padding:0 3 0 0; margin:0 10 10 10; overflow:hidden; } .page{ height:100%%; width:100%%; display:none; overflow:none; } .page[open=true] { display:block; } .page[open=false] { display:none; }
这里注意: 页面中定义了自定义属性open ,其实他可以是任何名字, 主要是你需要在csss!事件里对应修改下名字而已,
在选项卡事件里,定义互动操作
.tab{ background-image:url(img\main_tabbtn_normal.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position: 1px 25px 1px 10px; height:32px; margin:0 -7 0 0; vertical-align:middle; padding:0 5 0 15; width: calc( max-intrinsic-width() + 25px ); active-on!: parent = self.parent(), parent.$1(.tab:checked):checked = false , self:checked = true, main_el = $1(div#tabArea) , open_page = main_el.$1(div.page[open=true]) , open_page.open = false , open_page = main_el.child(self:index) , open_page.open = true ; assigned!: parent = self.parent() , check_tab = parent.$1(.tab[checked]), check_tab:checked = true , page_area = $1(div#tabArea) , page_area.child(check_tab:index).open = true ; }
上面基本上就是tab这种控件的使用方式了, 记住即可.
tabs的页面其实可以和aardio的tabs一样, 直接引用其他页面.
要用到include功能, 例如下面我第二个选项卡里引用two.html这个页面
<div #tabArea> <div .page>首页----页面演示</div> <div .page><include src="two.html" > Miss lesson.htm</include></div> <div .page>管理人员----页面演示</div> <div .page>信息记录----页面演示</div> </div>
two.html页面里我写下面的演示代码
<select name="country" size=1> <OPTION VALUE=1 >Afghanistan</OPTION> <OPTION VALUE=2 >Albania</OPTION> <OPTION VALUE=3 >Algeria</OPTION> <OPTION VALUE=4 >American Samoa</OPTION> </select>
可以看到
给pageArea内容区增加个列表:
新建个lesson.html和lesson.css文件
并添加一个pageBar工具条
<style type="text/css"> @import "lesson.css"; </style> <div #pageBar> </div>
定义下pageBar的css样式
#pageBar{ background-color:rgba(0,0,0,0.2);//随便写的,为了更好的观察 width:100%; height:38px; flow:horizontal; vertical-align:middle; }
添加点项目进去
<div #pageBar> <div #pagehome .btn-bar>信息汇总</div> <div #pagedir></div> <div #pageadd .btn-bar>添加上课信息</div> <div #space></div> <div #pagefind .btn-bar>搜索</div> <div #pagetoday .btn-bar>今日</div> <div #pageweek .btn-bar>本周</div> <div #pagemonth .btn-bar>本月</div> <div #pageall .btn-bar>全部</div> </div>
首先定义下.btn-bar的css样式, 在专门定义下pagedir的样式
#pagedir{ background-image:url(img\nextbtn_normal.png); background-repeat:no-repeat; width:16px; height:14px; } .btn-bar{ height:22px; width: max-intrinsic; vertical-align:middle; padding:0 2 0 2; margin:0 5 0 0; }
给这些项目添加图片
<div #pageBar> <div #pagehome .btn-bar><img src="img\message_localmes.png" />信息汇总</div> <div #pagedir></div> <div #pageadd .btn-bar><img src="img\add.png" />添加上课信息</div> <div #space></div> <div #pagefind .btn-bar><img src="img\search_16.png" />搜索</div> <div #pagetoday .btn-bar><img src="img\calendar.png" />今日</div> <div #pageweek .btn-bar><img src="img\week.png" />本周</div> <div #pagemonth .btn-bar><img src="img\month.png" />本月</div> <div #pageall .btn-bar><img src="img\refresh.png" />全部</div> </div>
图片大小高低不一, 那么我们去定义下img属性
.btn-bar img{ vertical-align: middle; margin:0 2 0 0; }
定义一下按钮效果:
.btn-bar:hover{ background-image:url(img\allbtn_highlight.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position:5 5 5 5; } .btn-bar:active{ background-image:url(img\allbtn_down.png); background-repeat:expand stretch-left stretch-middle stretch-right; background-position:5 5 5 5; }
效果已经出来了.
下面继续添加内容:
注意: 为了以后更好的维护, 每次分行的时候, 最好用div给套一层, 也便于样式管理
添加一个表格
<div #pageTable> <table #tab-style> <tr> <td>序号</td> <td width=150>Yoga馆</td> <td width=120>时间段</td> <td width=100>日期</td> <td width=60>会员数</td> <td width=80>性质</td> <td width=50>酬金</td> <td width=80>支付状态</td> <td>备注</td> </tr> </table> </div>
#pageTable{ width:100%%; height:100%%; background-color:rgba(255,0,55,0.2);//临时的 overflow:none; padding: 1 10 5 7; margin:0 0 5 0; }
下面定义表格样式#tab-style
#tab-style{ width:100%%; height:100%%; border:1 solid rgba(162,208,224,0.5); border-radius:4; background-image: url(img\tab_bk.png) ; background-position: 5 5 5 5; background-repeat:expand stretch-left stretch-middle stretch-right; }
设置了表格充满空间, 边框宽度1,颜色,圆角4, 表格的背景图片
嗯??!! 表格怎么跑到中间去了.......
于是, 增加一条
overflow:auto;
表头又回去了, 还好.
下面继续, 定义表格的边框, 这里定义每列
#tab-style > tr > td { padding:2 3 2 3; height:20px; border:1 solid rgba(162,208,224,0.5); color:#000; }
看到表格之间竟然有白条...... , 于是在tab-style属性里添加
border-spacing:0;
白条消失了, 但是表格之间看着很不自然啊,像素和底部那个都不一样, 底部线条明显清晰且细,判断是两个边框重叠导致的, 这样去掉顶部的边框和右侧的边框,应该就可以了.
那么, 第一行所有的列的顶部都不要
#tab-style > tr:first-child > td { border-top:none; }
顶部的粗线消失了, 再接再厉, 第一行所有的列的右侧也不要, 额..... , 不对, 这样处理之后还需要对以后的数据列执行同样的操作, 那么不如这样写: 所有的数据列的右边都不要
#tab-style > tr > td { border-right:none; }
清爽了, 但是第一行的最左边边框和外框重合加粗还在....那么,执行两个第一?
不对, 以后的数据只要是第一列的其实也是不能有左边框的吧?
那么,就删掉所有第一列的左边框
#tab-style > tr > td:first-child { border-left:none; }
完美了.
试着增加一下模拟数据, 看看效果如何
<div #pageTable> <table #tab-style> <tr> <td>序号</td> <td width=150>Yoga馆</td> <td width=120>时间段</td> <td width=100>日期</td> <td width=60>会员数</td> <td width=80>性质</td> <td width=50>酬金</td> <td width=80>支付状态</td> <td>备注</td> </tr> <tr> <td>1</td> <td width=150>上海闸北</td> <td width=120>20:04</td> <td width=100>2020.04</td> <td width=60>54</td> <td width=80>vip</td> <td width=50>20000</td> <td width=80>已支付</td> <td>人很好,爱笑!</td> </tr> <tr> <td>2</td> <td width=150>上海松江</td> <td width=120>5:37</td> <td width=100>2015.07</td> <td width=60>22</td> <td width=80>vip</td> <td width=50>46700</td> <td width=80>已支付</td> <td>哈哈哈哈哈哈!</td> </tr> <tr> <td>3</td> <td width=150>上海浦东</td> <td width=120>14:57</td> <td width=100>2021.09</td> <td width=60>165</td> <td width=80>普通会员</td> <td width=50>7800</td> <td width=80>已支付</td> <td>试试,体验...</td> </tr> </table> </div>
顶部有重合!!
删掉它
把之前的
#tab-style > tr:first-child > td
改为
#tab-style > tr > td { border-top:none; }
完美.
额,,,第一列要居中怎么办, 加个文本center
#tab-style > tr > td:first-child { border-left:none; text-align:center; }
其他的, 需要的话就自己考虑吧
提示下: 还能设置文本的颜色的哦, 可以利用csss! 来做
一般情况, 不希望表头随着内容移动, 那么可以固定死,table里添加
<div #pageTable> <table #tab-style fixedrows=1 rowcheck> <tr>
table中加入动态鼠标交互:
首先, 加入鼠标hover单元行变色
#tab-style > tr:hover { background-color:rgba(0,88,55,0.2); //color:red; }
再加入,鼠标点击选中单行, 注意排除掉 表头
#tab-style > tr:not(:first-child) { active-on!: $1(#tab-style > tr:checked):checked = false , self:checked = true; }
这里简单说下上面的写法 , active-on!: 意思是鼠标单击的时候触发
$1(#tab-style > tr:checked)
仔细看 , 是不是和它自己的属性一致, 这个其实就是css属性选择器,
意思是我要操作#tab-style节点下面的tr节点 , 只操作状态是checked的属性, 让它=false
ok.
上一个楼层已经定义过被选中(checked)后的颜色变化状态, 所以可以看到变化了.
可以从动态图上看到, 表头也被我鼠标hover的时候改变颜色了, 这个明显是不对的, 所以, 修改下鼠标经过的css hover属性:
#tab-style > tr:not(:first-child):hover { background-color:rgba(0,88,55,0.2); //color:red; }
不要被它那么长的属性给吓到了, 其实就是一个个属性加了::::::连接起来而已
表格中增加右键菜单:
首先在html中定义右键菜单列表, 并设置它的名字为tableMenu
<menu.context #tableMenu> <li id="i1">编 辑</li> <li id="i2">删 除</li> <li id="i3">插 入</li> <li id="i4">新 增</li> </menu>
之后在css属性里, 在 tr 行属性里引用这个tableMenu菜单
#tab-style > tr:not(:first-child) { //增加下句即增加右键菜单 context-menu:selector(menu#tableMenu); //单击功能 active-on!: $1(#tab-style > tr:checked):checked = false , self:checked = true; }
这里需要注意: 右键菜单的写法, 记住即可
后面有别的事, 会更新的慢很多, 也有可能几天不更一下
言归正传:
接上文, 菜单我们已经弄出来了, 不知道你有没有考虑过怎么去获取到我点了哪个菜单, 并且或获取我是从哪个table的tr行点的右键, 如果这些都获取不到, 那么就不能进行交互了
获取右键菜单很简单, 在aardio中执行下面代码
wbLayout.onMenuItemClick = function (ltTarget,ltOwner,reason,behaviorParams) { //获取选中的菜单内容 console.log(ltTarget.innerText); //获取从哪行tr点击来的 var dddd = wbLayout.$1("#tab-style >tr:checked"); console.dump(dddd.index()); }
有了上面两个属性值, 就可以调用菜单功能和对表格进行操作了.
迟到的更新: ( ̄▽ ̄)"
书接上文, 上面我们说到获取到了那两个值就可为所欲为了, 那么如果要去响应鼠标的菜单, 具体该如何做呢??
操作DOM即可.
我们知道表格的结构如下:
<table #tab-style> <tr> .... </tr> <tr> .... </tr> </table>
那么我们就去找#tab-style节点下面的tr即可, tr相对于#tab-style就是它的子节点(child) , 我们来删除它.
插入数据的话, 需要
先创建一个节点 例如这里的 tr
把这个节点插入到html里 , insert可以选择插入位置
插入后就可以修改这个节点里面的内容了 , 你可以每个td都赋值, 也可以直接给赋值他html内容
wbLayout.onMenuItemClick = function (ltTarget,ltOwner,reason,behaviorParams) { //获取选中的菜单内容 console.log(ltTarget.innerText,ltTarget.index()); //获取从哪行tr点击来的 var tabChecked = wbLayout.$1("#tab-style >tr:checked"); select(ltTarget.index()) { case 2 {//删除 console.log("共有多少个孩子=", wbLayout.$1("#tab-style").childCount() ); console.log("删除掉这个孩子=", wbLayout.$1("#tab-style").child(tabChecked.index()).delete() ); } case 3 {//插入 var tr = wbLayout.createEle("tr"); wbLayout.$1("#tab-style").insert(tr,tabChecked.index()); tr.innerHTML= "<td>999</td> <td width=150>上海浦东</td> <td width=120>14:57</td> <td width=100>2021.09</td> <td width=60>165</td> <td width=80>普通会员</td> <td width=50>7800</td> <td width=80>已支付</td> <td>试试,体验...</td>"; } case 4 {//新增 wbLayout.$1("#tab-style").insertAdjacentHTML("beforeEnd","<tr> <td>100</td> <td width=150>上海浦东</td> <td width=120>14:57</td> <td width=100>2021.09</td> <td width=60>165</td> <td width=80>普通会员</td> <td width=50>7800</td> <td width=80>已支付</td> <td>试试,体验...</td> </tr>") } else { } } }
另外, 不推荐用insertAdjacentHTML 虽然看起来确实方便, 最好使用操作节点dom的方式.
登录后方可回帖
由于用htmlayout来做界面, 那么需要把窗体设置为无边框
设置完成后, 界面不能再被调整大小了, 那么在mainform.aardio中需要加入
以便以后可以拖动调整界面大小.
那么, 如果下面修改了html代码, 每次去启动下工程也是个麻烦事, 而且不利于实时的看到修改后效果
我这里在界面里添加个定时器, 定时去刷新界面, 这样就可以模拟实时效果了