客户端行为

某些行为在客户端用JavaScript代码处理更为合适,例如动画和图像转滚(image rollovers)。为了在客户端执行JavaScript 代码,ZK引入了客户端行为(CSA)的概念。使用CSA,开发人员可以监听任何JavaScript事件且在客户端执行JavaScript代码。

CSA类似于事件监听器,除了CSA的行为是用JavaScript 编写的且在客户端执行。ZK允许开发人员为任何 JavaScript事件指定行为,例如onfocus, onblur, onmouseoveronmouseout,只要你的目标浏览器支持它们。

CSA的语法如下。

action="[onfocus|onblur|onmouseover|onmouseout|onclick|onshow|onhide...]: javascript;"

注意CSA是完全独立于ZK事件监听器的,尽管它们或许有相同的名字,例如onFocus。不同点包括:

  1. CSA在客户端执行,且在服务器端的ZK事件将监听器被调用前发生。

  2. CSA代码用JavaScript编写,而ZK事件将监听器用Java编写。

  3. CSA可以注册你的目标浏览器允许的任何事件,而ZK近仅支持在事件(Events)章节中列出的事件。

引用一个组件

在JavaScript 代码中,你可以通过晚捆绑(late-binding)EL表达式来引用一个组件或其它对象。晚捆绑EL表达式以 #{开始且以}结束,如下所示。

<button action="onmouseover: action.show(#{parent.tip})"/>

晚捆绑EL表达式在响应阶段被赋值。另外,如果一个EL表达式以${开始,则它会在组件创建阶段被赋值,在为action属性赋值前。例如,

<button action="onfocus: action.show(${tip}); onblur: action.hide(${tip})"/>
<div id="tip" visible="false">...</div>

将等价于

<button action="onfocus: action.show(); onblur: action.hide()"/>
<div id="tip" visible="false">...</div>

由于tip组件在为action属性赋值时才会被创建。

由于ZUML加载器(loader)并不知道CSA,它调用toString方法将组件转换成一个字符串,所以即使在为action属性赋值前创建了被引用组件仍是不正确的。

当然,这并不防碍你在某一action内使用${},如下所述。仅需记住它是在为action属性赋值前辈赋值的。

<variables myaction="onfocus: action.show(#{tip}); onblur: action.hide(#{tip});"
<button action="${myaction} onmouseover: action.show(#{parent.parent.tip})"/>

一个onfocus和的onblur例子

在下面的例子中,我们展示了如何使用CSA来提供在线帮助。当用户改变了任一个文本框的聚焦时,一条帮助消息就会据此显示。

<grid>
   <columns>
      <column/>
      <column/>
      <column/>
   </columns>
   <rows>
      <row>
<label value="text1: "/>
<textbox action="onfocus: action.show(#{help1}); onblur: action.hide(#{help1})"/>
<label id="help1" visible="false" value="This is help for text1."/>
      </row>
      <row>
<label value="text2: "/>
<textbox action="onfocus: action.show(#{help2}); onblur: action.hide(#{help2})"/>
<label id="help2" visible="false" value="This is help for text2."/>
      </row>
   </rows>
</grid>

强制规则

ZUL组件实际上是将一个EL表达式 (#{}) 转换为合适的JavaScript代码,基于结果对象的类。

  1. 若结果为null,则用null替换。

  2. 若结果为一个组件,则用$e('uuid')替换, $e 处为一个返回HTML 标签引用的JavaScript函数,uuid为组件的UUID。

  3. 若结果为一个Date对象,则用new Date(milliseconds)替换。

  4. 否则。结果调用toString方法将结果转换为一个字符串,然后用'result in string'替换。

onshowonhide 行为

onshowonhide行为被用于控制显示及隐藏一个组件的视觉效果。

改变window如何出现的例子

<zk>
   <button label="Show Overlapped" onClick="win.doOverlapped();"/>
   <window id="win" border="normal" width="200px" mode="overlapped"
action="onshow:anima.appear(#{self});onhide:anima.fade(#{self})" visible="false">
      <caption image="/img/inet.png" label="Hi there!"/>
      <checkbox label="Hello, Effect!"/>
   </window>
</zk>

CSA JavaScript工具

为节简化CSA编程,ZK提供了一些你可以利用的工具对象。

action对象

可用于任何对象的基本工具。

函数

描述

action.show(cmp)

使一个组件可见。

cmp – 组件。 使用 #{ EL-expr } 标识它。

action.hide(cmp)

使一个组件不可见。

cmp – 组件。 Use #{EL-expr} 标识它。

提示: 对于JavaScript程序员,直接操纵样式用于显示是很平常的。但是,这并不是一个好主意。而是使用action.show and action.hide代替,因为ZK客户端引擎必须处理视觉效果,bug workaround,等等。

comm对象

用于与服务器通信。

函数

描述

comm.onClick(cmp, info)

发送onClick事件至服务器。

cmp – 组件,使用#{EL-expr}或this指定它。

info – 一个字符串或null用于提供额外的信息。它会成为MouseEventgetArea的返回值。

comm.onUser(cmp, ...)

onUser事件发送至服务器。

cmp – 组件,使用#{EL-expr}或this指定它。

other – 你可以提供很多参数。

comm.onEvent(cmp, evt, ...)

将指定的事件发送至服务器。

cmp – 组件,使用#{EL-expr}或this指定它。

evt – 事件名称 例如, onUser

other – 你可以提供很多参数。

例如,

<window title="Test of JavaScript Utilities">
   <html onClick='l.value = "onClick "+event.area'
      onUser='l.value ="onUser " +org.zkoss.lang.Objects.toString(event.data)'><![CDATA[
      <a href="javascript:;" onclick="comm.sendClick(this, 'Hi')">onClick with Hi</a>
      <a href="javascript:;" onclick="comm.sendClick(this)">onClick with null</a>
      <a href="javascript:;" onclick="comm.sendUser(this)">onUser with null</a>
      <a href="javascript:;" onclick="comm.sendUser(this, 'One')">onUser with One</a>
      <a href="javascript:;" onclick="comm.sendUser(this, 'One', 'Two')">onUser with [One, Two]</a>
      <a href="javascript:;" onclick="comm.sendEvent(this, 'onUser', 'XYZ')">onUser with XYZ</a>
   ]]></html>
   <separator/>
   <label id="l"/>
</window>

anima对象

动画般的视觉效果。基于script.aculo.us [50] 提供的Effect 类。API被简化了。若你想要更多的视觉效果或空间,可以直接访问Effect

注:Effect要求组件使用DIV标签包围。并不是所有的ZUL组件都以这种方式被实现。若你有疑问,可以与div组件嵌套使用,如下。

<window>
   <div id="t" visible="false"
   action="onshow: anima.slideDown(#{self}); onhide: anima.slideUp(#{self})">
      <div><!-- the 2nd div is optional but sometimes it looks better with it -->
         <groupbox>
            <caption label="slide down"/>
            Hi <textbox/>
         </groupbox>
         When? <datebox/>
      </div>
   </div>
   <button label="toggle" onClick="t.visible = !t.visible"/>
</window>

当然,你加载的其它库并没有这个限制。

函数

描述

anima.appear(cmp) anima.appear(cmp, dur)

通过增加透明度(opacity)来使组件可见。

cmp – 组件。使用 #{EL-expr} 标识它。

dur – 以毫秒为单位的持续时间(duration)。 默认: 800。

anima.slideDown(cmp) anima.slideDown(cmp, dur)

以滑盖式(slide-down )效果来使组件可见。

cmp – 组件。使用 #{EL-expr} 标识它。

dur – 以毫秒为单位的持续时间。默认: 400。

anima.slideUp(cmp) anima.slideUp(cmp, dur)

以滑起来(slide-up)效果来使组件不可见。

cmp – 组件。使用 #{ EL-expr } 标识它。

dur – 以毫秒为单位的持续时间。默认:400。

anima.fade(cmp) anima.fade(cmp, dur)

通过褪色组件不可见。

cmp – 组件。使用 #{ EL-expr } 标识它。

dur – 以毫秒为单位的持续时间。默认:550。

anima.puff(cmp) anima.puff(cmp, dur)

通过膨胀(puff out)使组件不可见。

cmp – 组件。使用 #{ EL-expr } 标识它。

dur – 以毫秒为单位的持续时间。默认: 700。

anima.dropOut(cmp) anima.dropOut(cmp, dur)

通过褪色及放下(drop)使组件不可见。

cmp – 组件。使用 #{ EL-expr } 标识它。

dur – 以毫秒为单位的持续时间。默认: 700。

例如,

<window title="Animation Effects">
   <style>.ctl {
   border: 1px outset #777; background:#ddeecc;
   margin: 2px; margin-right: 10px; padding-left: 2px; padding-right: 2px; }
   </style>
   <label value="Slide" sclass="ctl"action="onmouseover: anima.slideDown(#{t}); onmouseout: anima.slideUp(#{t})"/>
   <label value="Fade" sclass="ctl"action="onmouseover: anima.appear(#{t}); onmouseout: anima.fade(#{t})"/>
   <label value="Puff" sclass="ctl"action="onmouseover: anima.appear(#{t}); onmouseout: anima.puff(#{t})"/>
   <label value="Drop Out" sclass="ctl"action="onmouseover: anima.appear(#{t}); onmouseout: anima.dropOut(#{t})"/>
   <div id="t" visible="false">
      <div>
      <groupbox>
         <caption label="Dynamic Content"/>
         Content to show and hide dynamically.
         <datebox/>
      </groupbox>
      Description <textbox/>
      </div>
   </div>
</window>



[50] http://script.aculo.us provides easy-to-use, cross-browser user interface JavaScript libraries