import
web.layout.debug;
wbLayout.attachEventHandler( web.layout.debug );
上面的代码用于输出HTMLayout引擎内置的调试信息到控制台,
并且添加一个全局函数 debug() 用于在CSSS!脚本中向控制台输出内容。
添加了这两行代码以后,如果我们的HTML,CSS书写有错误会自动打开控制台并显示错误信息.
再次运行修改后的代码,看看发生了什么?!
仍然没有显示任何错误信息,这说明我们所有的代码至少在语法上是正确的。
我们实在找不到原因,咒骂开发工具远水救不了近火,
于是我决定使用排除法,首先我跑去运行了一下aardio自带的behavior范例居然一切正常。
我看了一下范例中用的是div而不是button,难道是这个button有什么问题。
于是我修改上面的范例改成使用div
-
import win.ui;
-
/*DSG{{*/
-
var winform = ..win.form( right=599;bottom=399;text="HTMLayout - 自定义behavior";)
-
winform.add( )
-
/*}}*/
-
-
import web.layout;
-
var wbLayout = web.layout( winform )
-
-
namespace web.layout.behavior.command {
-
-
onMouseClick = function (ltTarget,ltOwner,x,y,ltMouseParams) {
-
ltOwner.innerHTML = "鼠标点击了!"
-
}
-
}
-
-
wbLayout.html = /**
-
<div id="my-button">点击这里</div>
-
**/
-
-
wbLayout.css = /**
-
#my-button{
-
behavior:command;
-
}
-
**/
-
-
winform.show()
-
win.loopMessage();
复制代码
注意对于div这样的普通节点并没有 onButtonClick 这样的按钮事件,
只有 onMouseClick 这样的鼠标事件. 而按钮没有 onMouseClick 事件(只能使用 onButtonClick )。
运行上面的代码,点击后节点里面的文字变成了 "鼠标点击了!",behavior工作了。
可是为什么改成button就没有反应呢?请试试你能不能找出答案?!
添加 behavior
HTMLayout有很多内建的behavior,
例如 button节点这样的按钮就默认拥有内建behavior:button。
-
-
#my-button{
-
behavior:command;
-
}
-
复制代码
在前面我们使用上面的代码给一个button节点指定自定义behavior时,就覆盖并清除了默认拥有的behavior。
也就是说他虽然有button的默认CSS样式外观,却在行为上不再是一个button了,当然鼠标点击的时候也就不再触发 onButtonClick 事件,而是象普通的div等节点一样触发 onMouseClick ,这就是我们在前面失败的原因。
所以这时候我们需要添加behavior,就是给节点添加新的behavior但是又不覆盖节点已经拥有的behavior.
在HTMLayout中使用波浪号表示添加behavior,例如: behavior:~command; 波浪号在名字前面表示追加behavior,波浪号在名字后面表示插入behavior,你可以把 ~ 理解为原来的behavior列表。
如果要同时为节点指定多个behavior,则可以使用空格分格,例如:
-
-
#my-button{
-
behavior:button command;
-
}
-
复制代码
所以我们同时指定多个behavior,或者使用了个 波浪号 都可以解决前面遇到的问题,正确代码如下:
-
import win.ui;
-
/*DSG{{*/
-
var winform = ..win.form( right=599;bottom=399;text="HTMLayout - 自定义behavior";)
-
winform.add( )
-
/*}}*/
-
-
import web.layout;
-
var wbLayout = web.layout( winform )
-
-
namespace web.layout.behavior.command {
-
-
onButtonClick = function (ltTarget,ltOwner,reason,behaviorParams) {
-
/*
-
当用户点击按钮时,
-
使用 innerHTML 属性改变节点内部的HTML代码,
-
inner是内部的意思,innerHTML就是指的节点内部的HTML代码
-
*/
-
ltOwner.innerHTML = "谢谢!"
-
}
-
}
-
-
wbLayout.html = /**
-
<button id="my-button">据说在html里可以使用button表示一个按钮</button>
-
**/
-
-
wbLayout.css = /**
-
#my-button{
-
behavior:~command; /*用波浪号追加 behavior */
-
}
-
**/
-
-
winform.show()
-
win.loopMessage();
复制代码
然后切换到代码视图,在
import
web.layout; 后面添加
import
web.layout.behavior.windowCommand; 以导入标准库实现的behavior
然后我们在HTML中添加一个简单的标题栏和关闭按钮
wbLayout.html =
/**
<div #title-bar>
<a>关闭窗口</a>
最后在CSS中为标题栏应用
windowCommand 这个 behavior,CSS代码如下:
wbLayout.css =
/**
#title-bar{
behavior:windowCommand;
windowCommand 这个behavior(交互行为)会监听用户的操作,
并且在回调事件中读取节点的 command 属性以决定执行什么样的命令,
所以我们需要为标题栏里的节点指定 command 属性以执行对应的命令。
在标准库中打开web.layout.behavior.windowCommand; 的源代码 可以看到 command 可以指定为以下属性:
command = "window-caption" 表示鼠标左键按住该节点可以拖动窗口
command = "window-close" 关闭窗口
command = "window-min" 最小化窗口
command = "window-max" 最大化窗口
command = "window-restore" 恢复窗口
所以我们修改HTML如下
wbLayout.html =
/**
<div #title-bar command="window-caption">
<div .ctrl-bar>
<a command="window-close">r</a>
</button>
然后我们简单的改进一下CSS外观
wbLayout.css =
/**
html{
background:#999;/*网页背景色*/
border-radius:4px; /*8像素大小的圆角*/
#title-bar{
behavior:windowCommand;
width:100%; /*宽度撑满窗口*/
height:22px; /*指定高度*/
background:#CCCCCC; /*背景色*/
/*CSS选择器中,空格表示节点间的父子包含关系*/
#title-bar .ctrl-bar{
//标题栏按钮容器绝对定位到窗口右上角
top:0px;//顶坐标1像素
right:8px;//右坐标5像素
#title-bar a[command]{
display:block; //显示为块节点
float:left;//块节点左浮动,如果有多个按钮可以从左向右排
height:16px;
font-family:"Marlett";/*这个字体把小写r显示为关闭符号*/
padding:4px;
#title-bar a[command]:hover{
background:#999;
**/
使用 border-radius:8px; 指定了网页使用圆角,我们运行程序以后,发现网页虽然圆角了,
但是winform窗体并没有圆角而是显示不协议的黑色背景,这里我们要请出标准库里的 win.util.round 把窗体也改造成圆角。
import
win.util.round;
win.util.round( winform );
你可能注意到了关闭按钮是这样写的 <a>关闭窗口</a>
a标签
是一个超链接,超链接类似普通文本、
span标签
是一个内联节点(区别是超链接可以使用href属性指定点击打开的网址),所谓内联节点主要是指其不能向块节点(例如div节点)那样指定与高度有关的样式、内联节点会自左向右流动布局(类似文本那样水平流动)。关于内联节点与块节点的区别可参考教程
《HTML - DIV,CSS 布局基础》
所以我们需要在CSS中指定 display:block; 将超链接转换为块模式(可以指定大小),
并且在CSS中用 float:left; 指定了向左浮动( 块默认是自上向下布局的,左浮动可以水平排放块节点 )关于块节点、左浮动等知识请参考
《DIV,CSS布局快速入门》
,
那么您可能会问:“为什么不直接用
button标签
来表示关闭按钮呢?” - 这是 web.layout.behavior.windowCommand 里的一个特殊设定 - 将button预留给了可能出现在标题栏内的导航按钮( 例如
仿360界面
)。
<div .ctrl-bar> </div>
这个DIV容器准备用来放所有的标题栏按钮(虽然目前只有一个关闭按钮)
在HTML里可以用div对节点分组、划分空间,例如这里的.ctrl-bar 可以绝对定位到窗口的右上角 - 如果有多个按钮(例如最大化、最小化等)就不用一个个的去调整到右上角了。在CSS中指定以使用绝对定位方式。
最终代码如下:
-
import win.ui;
-
/*DSG{{*/
-
var winform = ..win.form( bottom=399;text="HTMLayout - 无边框窗口";border="none";right=599 )
-
winform.add( )
-
/*}}*/
-
-
import win.util.round;
-
win.util.round(winform,,,6,6); //窗体改成圆角,最后两个参数指定圆角半径
-
-
import web.layout;
-
import web.layout.behavior.windowCommand;
-
-
var wbLayout = web.layout( winform )
-
-
wbLayout.html = /**
-
<div #title-bar command="window-caption">
-
<div .ctrl-bar>
-
<a command="window-close">r</a>
-
</button>
-
</div>
-
**/
-
-
wbLayout.css = /**
-
html{
-
background:#999;/*网页背景色*/
-
border-radius:4px; /*8像素大小的圆角*/
-
}
-
-
#title-bar{
-
behavior:windowCommand;
-
width:100%; /*宽度撑满窗口*/
-
height:22px; /*指定高度*/
-
background:#CCCCCC; /*背景色*/
-
-
}
-
-
/*CSS选择器中,空格表示节点间的父子包含关系*/
-
#title-bar .ctrl-bar{
-
//标题栏按钮容器绝对定位到窗口右上
-
top:0px;//顶坐标1像素
-
right:8px;//右坐标5像素
-
}
-
-
/*CSS选择器中,方括号指定节点拥有的属性*/
-
#title-bar a[command]{
-
display:block; //显示为块节点
-
float:left;//块节点左浮动,如果有多个按钮可以从左向右排
-
height:16px;
-
font-family:"Marlett";/*这个字体把小写r显示为关闭符号*/
-
padding:4px;
-
-
}
-
-
#title-bar a[command]:hover{
-
background:#999;
-
}
-
**/
-
-
winform.show()
-
win.loopMessage();
复制代码
在aardio编辑器中粘帖上面的代码,按F5快捷键运行效果如下:
当然,我们也不必要把HTML,CSS都写在一个文件里。
可以创建一个aardio工程文件,css可以写到单独的 *.css 文件里, html 可以写到单独的 *.html 范例里,
然后调用 web.go( "/res/my.html" ) 打开html即可,html,css都可以方便的加入内嵌资源生成独立绿色的EXE文件。
课后作业题
请修改课程中无边框窗口的源代码,要求如下:
1、 增加最大化、最小化等按钮,不得使用图片
2、 使窗体边框可以拖动调整大小
作业提示:
1、 Marlett 字体里的数字 0,1,2 分别是什么图案?
2、 在aardio里新建 HTMLayout UI 工程,里面用到了一个behavior: web.layout.behavior.windowSizer
3、 HTMLayout扩展的CSS语法中有一个 content 属性可以用来改变节点内容,例如:
-
-
div#my-id{ content:"文本"; })
-
复制代码
答案在下面:
-
-
import win.ui;
-
/*DSG{{*/
-
var winform = ..win.form(text="HTMLayout 无边框窗体";right=599;bottom=399;border="none";parent=...)
-
winform.add()
-
/*}}*/
-
-
import web.layout;
-
import web.layout.behavior.windowCommand;
-
import web.layout.behavior.windowSizer;
-
-
//创建网页浏览器
-
var wbLayout = web.layout( winform )
-
-
wbLayout.html = /**
-
<html>
-
<body>
-
<!-- 下面是标题栏,凡在CSS中指定 behavior:windowCommand 的节点(含子节点) 可用 command 属性指明命令类型 -->
-
<div #title-bar command="window-caption"> <span .title> 我 的 软 件 </span>
-
<div .ctrl-bar>
-
-
<!-- 弹出菜单,类似这种包含弹出节点的最好用div或button,
-
div主要用作布局容器 - 可更好的支持弹出子节点或浮动子节点,
-
而a,li等节点存在的主要目的不是用来做其他节点的容器 -->
-
<div .window-menu>u
-
<menu .popup> <!-- .popup是内置的弹出菜单样式 -->
-
<li>在线帮助</li>
-
<li>子菜单
-
<menu >
-
<li>这是子菜单</li>
-
</menu>
-
</li>
-
<li #exit>退出</li>
-
</menu>
-
</div>
-
-
<!-- 下面是标题栏按钮,必须使用a标记表示,command属性指示该按钮执行的命令 -->
-
<a command="window-min">0</a>
-
<a command="window-max">1</a>
-
<a command="window-close">r</a>
-
</div>
-
</div>
-
-
<!--下面这句用来支持可拖动的边框,必须在aardio中调用 import web.layout.behavior.windowSizer -->
-
<div style="behavior:windowSizer"/>
-
</body>
-
</html>
-
**/
-
-
wbLayout.css = /**
-
-
body{
-
margin:0;
-
background:#fff;/*网页背景色*/
-
}
-
-
#title-bar{
-
behavior:windowCommand; /*必须在aardio中 import web.layout.behavior.windowCommand */
-
width:100%; /*宽度撑满窗口*/
-
height:28px; /*指定高度*/
-
background:#5a5a5a; /*背景色*/
-
}
-
-
/*最大化后body会自动添加maximize属性*/
-
body[maximize]{
-
border-radius:0;/*最大化去掉圆角*/
-
}
-
-
body[maximize] #title-bar{
-
border-radius:0;/*最大化去掉圆角*/
-
}
-
-
#title-bar span.title{
-
font:system;
-
margin:6px 0 0 10px;
-
color:#CCCCCC;
-
}
-
-
/*CSS选择器中,空格表示节点间的父子包含关系*/
-
#title-bar .ctrl-bar{
-
//标题栏按钮容器绝对定位到窗口右上角
-
top:1px;//顶坐标
-
right:8px;//右坐标
-
width:95px
-
}
-
-
/*CSS选择器中,方括号指定节点拥有的属性*/
-
#title-bar .ctrl-bar a{
-
display:block; //显示为块节点
-
float:left;//块节点左浮动( 从左向右排 )
-
height:14px;
-
font-family:"Marlett";/*该字体显示按钮符号*/
-
font-size:14px;
-
padding:4px;
-
color:#fff;
-
}
-
-
#title-bar a[command]:hover{
-
background:#6ebccf;
-
}
-
-
#title-bar a[command]:active{
-
background:#FF0000;
-
}
-
-
#title-bar a[command="window-restore"]{
-
content:"2";/*改变文本,Marlett字体为还原符号*/
-
}
-
-
#title-bar .window-menu{
-
behavior:popup-menu;
-
float:left;
-
height:14px;
-
font-family:"Marlett";/*该字体显示按钮符号*/
-
font-size:14px;
-
padding:4px;
-
color:#fff;
-
}
-
#title-bar .window-menu:hover{
-
background:#6ebccf;
-
}
-
#title-bar .window-menu:owns-popup /*菜单已弹出*/
-
{
-
background-color: #FF0000;
-
color: #FFFFFF;
-
}
-
**/
-
-
// 响应菜单点击事件
-
wbLayout.onMenuItemClick = {
-
-
// 事件可以是一个函数或列表,如果是列表键名匹配节点的id或name属性
-
exit = function (ltTarget,ltOwner,reason,behaviorParams) {
-
winform.close();
-
}
-
-
// 在这里没有匹配不到id的节点会触发default函数*/
-
default = function (ltTarget,ltOwner,reason,behaviorParams) {
-
var ltPopupOwner = web.layout.element( behaviorParams.he );//这是弹出菜单的按钮节点
-
winform.msgbox( ltTarget.innerText )
-
}
-
}
-
-
import win.ui.shadow;
-
win.ui.shadow(winform); //添加阴影边框
-
-
winform.show();
-
win.loopMessage();
-
-
复制代码
运行效果: