1.概述
evml设计的出发点,是通过添加少数几个DOM属性,来简化界面开发。html的原有定义被完整保留下来,开发人员完全可以把这些属性看作是html语言的自然延伸,而不是一个全新的架构。
要在DOM节点上添加自定义的物理属性,需要实现一个技术难题,即如何在设置了属性值之后,自动地改变该DOM节点的相应特征。针对不同浏览器,解决方法是不一样的,在IE下,通过onpropertychange来检测属性改变事件;在firefox中,则可以简单地通过__defineSetter__方法来实现。这样,我们就可以在DOM扩展属性改变时,触发相应的处理函数,改变DOM节点的物理特征。
从效率和简化方面考虑,evml对自定义属性的使用是非常有节制的。引入的属性,要不对代码简化有明显作用,要不是为了实现换肤功能,要不就是为了兼容各浏览器。pos属性简化了定位,还实现动态定位功能;bg属性简化了背景定义,可以实现三图背景,并支持换肤功能;color属性主要是为了实现换肤中的颜色切换;bd和pd属性把盒子模型统一为内缩方式,不管是在w3c标准的页面和非w3c标准的页面下都是这样;opacity属性则为了浏览器兼容,因为IE和firefox实现半透明的代码是不一样的。
本文前半部分介绍evml扩展属性的使用方法,后半部分简要列举了evml引挚中提供的js函数和方法,这些函数和方法,会对开发者的进一步开发很有帮助。
evml的官方发布地址是:http://www.script8.com/evml.js,最新的版本将发布到这上面。原则上,evml不会再作大幅度扩展,所有的修改都会向下兼容。开发者可以在页面中直接调用这个地址,也可以拷贝到本地任意目录。
2.如何使用evml
使用方法很简单,只要在页面中加载evml.js文件即可,不要求页面与evml.js同域,下面是一个简单的evml程序。
◇ 测试程序 - >> 运行下面的js |
<script src=http://www.script8.com/evml.js></script>
<body>
<div pos="c,m,100,60" bg="#green" bd="#007600"></div>
</body> |
如果cacheScene参数为true,则由开发者自定义渲染方法,这对处理图片预载比效有用。注意,document.body默认是隐藏的,这是为了不显示渲染前的页面,所以在evml_onload中,需要把其设置为显示状态。
◇ 测试程序 - >> 运行下面的js |
<script cacheScene=1 src=http://www.script8.com/evml.js></script> <body> <div pos="c,m,100,60" bg="#green" bd="#007600"></div> </body> <script>
function evml_onload(){
evml_initBody()
}
</script> |
evml中扩展出来的所有属性,不仅仅可以在html中设置,也可以由javaScript来动态改变,比如“oNode.pos="c,m,100,60"”,就可以重新定位DOM节点的位置,注意,这个定义用的直接是点定义,而不是setAttribute方法,这就能很好地简化代码和提高代码的可读性。
3.定位方法
在扩展的属性中,最重要的要数pos属性。定位是界面开发的基础,pos属性的基本格式是:“x,y,w,h”。evml也提供了更直观的x、y、w和h等几个属性,来进行局部调整,比如下面的几个语句是等同的:
<div style="position:absolute;left:50px;top:50px;width:100px;height:100px"></div>
<div pos="50,50,100,100"></div>
<div x="50" y="50" w="100" h="100"></div>
第一条语句是传统写法,第二条和第三条是evml写法,大家可以看到,代码明显简洁多了。pos属性添加了一些关键字,来实现相对定位的功能,比如居中,居下等功能,用于实现可变客户区的定位需求,下面是关键字列表。
c:水平居中
r:水平居右
m:垂直居中
b:垂直居右
f:水平或垂直方向充满父对象
最妙的是,这些关键字是可进行四则运算的,比如可以使用“f-100”来表示宽度,即宽度是父对象宽度减去100个像素。善用这个特性,大部分可变化布局就可以在不使用脚本支持的情况下实现。
如果只想改变其中的某些参数,而保留其它参数为原值,可以简单地把保留值设置为空字符串就可以了,比如“,,60,30”,这个定义就只改变宽和高,而不改变位置。
evml会自动识别是否绝对定位,如果定义了x或y,则自动设置DOM节点为绝对定位,如果没有定义这两项,DOM节点会保持默认的定位方式。
为了弥补代码定位直观性差的弱点,如果pos的前两项都是“*”号,则该DOM节点可以拖动,也可以使用方向键微调位置,并在位置变动时,自动保存当前坐标,开发者只需把DOM节点定位到满意的位置,然后在代码编辑器中的“*,*”位置Ctrl+v即可。
◇ 测试程序 - >> 运行下面的js |
<script src=http://www.script8.com/evml.js></script>
<style>*{font-size:12px;cursor:default}</style> <body style=visibility:hidden> <div pos="100,100,160,60" bd="#black">普通定位<br>pos="50,50,160,60"</div>
<div pos="c,m,160,60" bd="#black">居中定位<br>pos="c,m,160,60"</div>
<div pos="r-60,b,160,60" bd="#black">居右偏移<br>pos="r-60,b,160,60"</div>
<div pos="*,*,160,60" bd="#black" bg="#white">拖放定位<br>pos="*,*,160,60"</div>
</body> |
4.背景
evml中使用到的图片,都是以bg形式来表示的,为了减少重复代码,定义了当前图片文件夹和公用图片文件夹,默认值都是“images/”,要改变他们的值有两种方法,一是在引入evml.js的script元素里指定folder和folder0属性,一是在js代码中改变Evml.folder和Evml.folder0的值。引入两个文件夹的原因,是为了实现动态换肤技术,在程序运行中,改变Evml.folder就可以实现换肤,而共用的图片存放在Evml.folder0中,避免图片的重复。如果图片定义最前面用“http:”字样,则作为网络图片处理。
bg属性支持使用颜色和图片作为背景,多个背景属性可以用空格分开,和css定义差不多。为了简化定义,没有使用url关键字特别说明是图片,而是借助了“#”字符和“.”字符来区分。如果字符串中包含“.”,那必定是图片路径,在这种情况下,如果第一个字符是“#”,则图片所在文件夹是公用图片文件夹。如果第一个字符是“#”,而字符串中没有“.”,则该字符串是颜色定义。
如果bg定义中有“_*”关键字,则使用经典的三图背景,即左右两张图片不变,中间图片拉伸,“_*”的位置,是由“_l”、“_c”和“_r”三张不同的图片组合而成。默认情况下,左右两张图的宽度都是9px,要改变默认值,需要在pos属性中添加第5项和第六项,分别是这两张图的宽度。
不管是单图还是三图,bg中的图片都支持png格式的半透明效果,这样就可以实现比较漂亮的界面效果。
上面说了这么多,是不是感觉挺复杂的,不过真正使用起来很简单,请看下面的例子:
◇ 测试程序 - >> 运行下面的js |
<script folder="photo/" src=http://www.script8.com/evml.js></script>
<style>*{font-size:12px;cursor:default}</style>
<body style="visibility:hidden"> <div pos="50,50,120,60" bg="#green">简单颜色背景</div>
<div pos="50,120,120,60" bg="winflag.gif">简单图片背景</div>
<div pos="50,190,120,60" bg="winflag.gif no-repeat center middle">单图背景居中</div>
<div pos="50,260,120,60" bg="winflag.gif no-repeat center middle #green">图片+颜色作为背景</div>
<label pos="50,340">三图背景</label>
<div pos="50,360,120,21" bg="bt_*.gif"></div> </body>
|
5.字体颜色
在设置背景时,我们就已经使用到了颜色,字体颜色的定义与其一样,也是用“#”开始的十六进制或英文单词。使用英文单词来表示颜色,evml的目的和css是不一样的,css只是让颜色的表达更直观,而evml则是为了换肤。evml提供了white,black,red,yellow,green,blue,orange,brown等八种英文表示的基础颜色,“#white”和“#ffffff”是等值的,开发者可以定义自已的英文颜色,在换肤时,只要把这种英文所对应的颜色值改变过来,然后调用evml_initNode函数重新渲染页面就行了。
◇ 测试程序 - >> 运行下面的js |
<script src=http://www.script8.com/evml.js></script>
<style>*{font-size:12px}</style>
<body style="visibility:hidden"> <div pos="50,50,100,60" bg="#green" bd="#black">color="#green"</div>
<div pos="50,120,100,60" bg="#myColor" bd="#black">color="#myColor"</div> </body> <script>
function evml_onload(){
Evml.colors["myColor"]="#ff0000"
evml_initNode(document.body)
document.body.style.visibility=""
}
</script> |
6.边框
为了简化逻辑,evml只支持单线边框,可以分别定义四条边的颜色。“bd="#black"” 表示四条边均为黑色,如果要分别订制各边,可以用“bd="#black #green #red #blue"”来表示左、上、右、下各边的颜色。单个的“#”号,表示没有这条边框,比如“bd="#black # # #blue"”,就只有左边框和下边框。
◇ 测试程序 - >> 运行下面的js |
<script src=http://www.script8.com/evml.js></script>
<style>*{font-size:12px}</style>
<body style="visibility:hidden"> <div pos="50,50,120,60" bg="#d4d0c8" bd="#black">bd="#black"</div>
<div pos="50,120,120,60" bg="#d4d0c8" bd="#red #blue">bd="#red #blue"</div>
<div pos="50,190,120,60" bg="#d4d0c8" bd="#red #red #black #black">bd="#red #red #black #black"</div>
<div pos="50,260,120,60" bg="#d4d0c8" bd="#red # # #black">bd="#red # # #black"</div> </body>
|
7.边距
边距的定义,与边框有类似之处,也是按照左、上、右、下的顺序逐个排列边距,中间用空格分开,如果自定义了一个数值,则四边的边距都等同。
◇ 测试程序 - >> 运行下面的js |
<script src=http://www.script8.com/evml.js></script> <style>*{font-size:12px}</style> <body style="visibility:hidden"> <div pos="50,50,120,60" bd="#black" pd="6">pd="6"</div> <div pos="50,120,120,60" bd="#black" pd="6 3 3 6">pd="6 3 3 6"</div> </body>
|
8.三态图片按钮
三态图片按钮是应用程序开发中的重要元素,它是由一张三态图片构成,在按钮发生鼠标事件时,分别显示不同的状态。我们只需要改变这张图片,就可以创造出千变万化的效果。
为了保持按钮的原生性,三态图片按钮不支持png格式的图片,如果需要柔化按钮边缘,可以在制作图片时,叠加底图背景就可以了。
三态图片按钮上面是可以显示文字的,这样可以解决很多按钮样式完全一样,只是文字不一样的问题。
给合bind属性,可以给按钮绑定一个感应区,这个功能对于实现文件选择框的美化很有好处。可以在按钮上放置文件选择框,把其半透明度设置为0,然后让按钮绑定它,这样发生在文件选择框上的事件,就会传递给按钮了,而点击文件选择框时,也符合文件上传安全机制。
善用tog属性,可以实现很多特殊的按钮,比如下拉选择框、单选钮和复选框。
◇ 测试程序 - >> 运行下面的js |
<script folder="photo/" src=http://www.script8.com/evml.js></script> <style>*{font-size:12px}</style> <body style="visibility:hidden"> <button pos="50,50,53,17" bg="button_a.gif"></button>
<button pos="50,120,82,15" bg="button_b.gif" pd="3 0 0 0" style="text-align:left">宋体</button>
<button bind="txOpen" pos="50,190,39,34" bg="button_c.gif"></button>
<div pos="50,190,39,34" style="overflow:hidden">
<input id="txOpen" pos="-30,0,39,34" type="file" hidefocus="1" size="1" opacity="0">
</div> </body>
|
9.半透明
加入半透明属性的理由很简单,就是为了统一IE和firefox下相应功能的代码。IE下本来使用“filter:alpha(opacity=50)”,和firefox下用“-moz-opacity:0.5”等同。在evml中,只需要“opacity="50"”就可以了。
◇ 测试程序 - >> 运行下面的js |
<script src=http://www.script8.com/evml.js></script> <style>*{font-size:12px}</style> <body style="visibility:hidden"> <div pos="50,50,120,60" bd="#black" bg="#green" opacity="50">opacity="50"</div> </body> |
10.拖拽
在evml中实现拖拽变得非常简单,只需要给DOM元素加入drag属性就行了。drag的参数值有this、parent两种,当参数值为this时,拖拽自已,当参数值为parent时,拖拽父元素。
默认情况下,拖拽设置了左、上、右三面禁区,这三个方向是不能拖出界外的,下方则不受限制。要限制拖拽的范围,可以在ondraging事件里自定义,具体方法是改变系统参数p的x或y属性。
◇ 测试程序 - >> 运行下面的js |
<script src=http://www.script8.com/evml.js></script> <style>*{font-size:12px}</style> <body style="visibility:hidden"> <div drag="this" pos="50,50,120,60" bg="#97C025">拖动自已</div>
<div pos="50,120,120,60" bg="#d4d0c8">
<div drag="parent" pos="0,0,f,20" bg="#405E98" color="#white">拖动父亲</div>
</div>
<div drag="this" ondraging="p.y=190" pos="50,190,120,60" bg="#6E9EF2">
左右拖动
</div> </body> |
11.动画
浏览器中一般都使用gif动画,不过gif动画有一些缺点,比如无法实现半透明,无法控制播放和暂停,以及播放的范围。evml中引入的动画功能,可以有效地弥补这些不足。
要实现evml动画,只需准备一张多态图片,横向和纵向均可单列或多列排布,然后在DOM节点上加入animate属性,其参数有三个,loop是单向循环播放,bounce是反弹循环播放,once是只播放一次。autoStart属性指定是否自动播放动画,interval属性指定桢之间的时间间隔。
需要在pos中加入参数,来指定水平和垂直方向上的桢数,这样pos的格式就变成了“pos="left,top,width,height,h-count,v-count"”
evml给动画元素提供了play和stop两种方法,play方法如果不带参数,则全部播放,第一个参数表示起始桢,每二个参数表示终止桢。
◇ 测试程序 - >> 运行下面的js |
<script folder="photo/" src=http://www.script8.com/evml.js></script> <style>*{font-size:12px}</style> <body style="visibility:hidden"> <div pos="50,50,104,12,1,5" animate="loop" autoStart="1" interval="100" bg="loading.jpg"></div>
<div pos="50,120,104,12,1,5" animate="bounce" autoStart="1" interval="100" bg="loading.jpg"></div> </body>
|
12.重要系统参数
isIE 是否IE浏览器,evml只支持IE和firefox
Evml.minWidth 最小客户区宽度,默认为480px
Evml.minHeight 最小客户区高度,默认为320px
Evml.colors 自定义颜色对象
Evml.isLocal 是否本机网页
Evml.isDTD 是否DTD标准页面
Evml.folder0 公用图片文件夹
Evml.folder 当前图片文件夹
Arg.version 用于文件版本控制
13.系统对象方法扩展
String.trim() 去两端空格
String.inc(str,sSplit) 判断字符串是否组包含,分隔符为sSplit(默认值“,”)
String.getCssArg(str,sDef) 取出css格式字符串中的参数值
String.getUrlArg(str,sDef) 取出url格式字符串中的参数值
Array.parseInt() 把数组的所有项都转化为整数
Array.deleteItem(item) 从数组中删除值等于item的项
Array.addItem(item) 在数组中加入item项,如果已经有等于item的项,则忽略
Function.bindNode(oNode) 给函数对象绑定this指针
13.提供给开发者的函数
$(oNode) 根据id取得DOM元素,如果oNode不是字符串,则返回其本身
$parent(oNode) 上溯祖辈节点,如果找到id不为空的,或是document.body下的顶级节点则返回
$pos(oNode) 返回DOM节点相对于客户区的坐标
$c(str) 取得自定义颜色的颜色值
encode(str) 对%、'、"、\n、\r、\、&、,、;、|、<、>等特殊字符进行编码
decode(str) 对经过encode的字符串进行还原
setUserData(sKey,sVal) 在客户端保存数据,IE中使用userdata,firefox中使用cookie来保存
getUserData(sKey) 取得保存在客户端的数据
writeToIframe(win,sData) 把数据写入到iframe中
loadImage(obj,foo,iOverTime)预载图片,载入数量改变时,会调用foo(iCount,iLoaded)
importJs() 载入js,使用该函数的原因,是为了实现代码版本控制
attachProperty(oNode,sAttr,foo)给DOM元素里的一个属性绑定函数,当属性改变时,就会触发执行该函数
deleteNode(oNode) 删除一个DOM节点
focuNode(oNode) 让一个DOM节点获得焦点
execFoo(foo) 执行函数,该函数可以是字符串形式或函数对象
createEvml(str,op,oRefer) 在DOM中插入生成evml代码
showPop(oNode) 把一个DOM节点作为pop窗口显示出来
clearPop() 隐藏当前pop窗口
evml_initNode(op) 使DOM节点evml化
loadData(sUrl,foo) 载入服务端数据,载入完成后执行foo(sData)