基于YUI 的YUI Bubbling Library最近发布了新版本,YUI Bubbling Library使用了Observer pattern (publish/subscribe pattern)
Observer设计模式
1、DOM Event Model
W3C DOM Level2的事件模型规范中,事件在DOM树中的传播过程(从根节点到目标节点)被分为了三个阶段:捕捉(Capture)、冒泡(Bubbling)、目标(Target)。Dom 事件触发后从Root根节点自上而下传播事件到 target 对象(此过程称为 Capture Phase),然后传播事件给 target 对象(此过程称为 Target Phase),最后在自下而上的传播事件(此过程称为 Bubbling Phase)。
一些有关DOM Event Model的资料:
- brainjar.com的The DOM Event Model
http://www.brainjar.com/dhtml/events/
http://www.brainjar.com/dhtml/intro/
- W3C Document Object Model Events
http://www.w3.org/TR/DOM-Level-2-Events/events.html
- Opera Event capture explained
http://dev.opera.com/articles/view/event-capture-explained/
- Mozilla DOM Event Reference
http://www.mozilla.org/docs/dom/domref/dom_event_ref.html
- Wikipedia DOM Events
2、DOM事件模型处理方法
事件模型的处理需要解决两个关键方面:
-
- 把一个事件和 HTML 元素绑定起来的方法。
- 在事件被触发后如何对之进行处理。
在apple开发人员联盟站点上有一篇文档“同时支持三种事件模型“对此讲述得很清晰和全面透彻。
-
-
事件绑定的方法
-
事件绑定是指构造一个响应系统或者用户动作的 HTML 元素的过程。在不同的浏览器版本中,有不少于五种事件绑定技术。
事件绑定方法I:绑定元素属性
<SCRIPT LANGUAGE="JavaScript"> function convertToUpper(textbox) { textbox.value = textbox.value.toUpperCase(); } </SCRIPT> ... <FORM ....> <INPUT TYPE="text" NAME="first_name" onChange="convertToUpper(this)"> <INPUT TYPE="text" NAME="last_name" onChange="convertToUpper(this)"> ... </FORM>
事件绑定方法II:绑定对象属性
document.forms[0].myButton.onclick = myFunc;使用此种绑定方法,在事件触发的时候,没有办法向事件函数传递参数
事件绑定方法III: 绑定 IE4+<SCRIPT FOR> 标识
事件绑定方法IV:使用 IE5/Windows 的 attachEvent() 方法
attachEvent()
方法的用法如下所示:elemObject.attachEvent("eventName", functionReference);eventName 参数的值是表示事件名称的字符串,比如
onmousedown
。functionReference 参数是一个不带括号的函数引用,和早些时候描述的事件属性方法中一样。事件绑定方法V:使用 W3C DOM 的 addEventListener() 方法
addEventListener()
方法的语法如下所示:nodeReference.addEventListener("eventType", listenerReference, captureFlag);
addEventListener()
方法为指定的结点注册了一个事件,表示该结点希望处理相应的事件。这个方法的第一个参数是一个声明事件类型的字符串(不带”on”前缀),比如click
,mousedown
,和keypress
。addEventListener()
方法的第二个参数可以和早些时候描述过的函数引用同样对待。第三个参数则是一个 Boolean 值,指明该结点是否以DOM中所谓的捕捉模式来侦听事件。对于一个典型的事件侦听器来说,第三个参数应该为false(假)
。
-
-
访问事件对象
-
IE4+ 的事件对象是
window
对象的一个属性,也即需要通过window.event来判断事件类型。这也意味着在所有的实例中只有一个事件对象。而对于 遵守W3C DOM的浏览器 来说,除了基于标识属性风格的绑定方法之外,其它绑定方法都是把事件对象自动传递给与事件相绑定的函数。传递给函数的是一个单一的参数。开发者需要在函数中定义一个参数变量,来“接收”该参数的值。为了避免和IE中的
window.event
对象互相冲突,请不要把参数命名为 event。举例来说,把它命名为evt
就相当好。兼容IE和W3C DOM事件对象引用
function myFunc(evt) { evt = (evt) ? evt : ((window.event) ? window.event : "") if (evt) { // process event here } }能够是被基于IE和W3C DOM事件后,由于DOM存在capture phase、target phase、bubbling phase,在事件传播过程中涉及许多节点,文档中的每一个结点都可以接收事件,一个典型问题是要区分evt.currentTarget和evt.target。W3C DOM结点的事件目标
有两种策略,一个策略是使用 W3C DOM 事件对象的
currentTarget
属性,该属性返回一个处理事件的结点的引用。脚本中的决策树需要考虑这个属性。function toggleHighlight(evt) { evt = (evt) ? evt : ((window.event) ? window.event : "") if (evt) { var elem if (evt.target) { if (evt.currentTarget && (evt.currentTarget != evt.target)) { elem = evt.currentTarget } else { elem = evt.target } } else { elem = evt.srcElement } elem.className = (evt.type == "mouseover") ? "highlight" : "normal" } }另一个可选的方法是考察由
target
属性返回的对象的 ronodeType
属性。一个能够把事件定向给文本结点的浏览器,也可以把一个文本结点的nodeType
属性值报告为3,而不是报告为元素结点的类型(其值为1)。如果事件的目标是一个文本结点,则脚本程序就可以通过该文本结点的parentNode
属性来得到其上级元素结点的引用。这种方法的决策树在某种程度上得到更多的改进:function toggleHighlight(evt) { evt = (evt) ? evt : ((window.event) ? window.event : "") if (evt) { var elem if (evt.target) { elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target } else { elem = evt.srcElement } elem.className = (evt.type == "mouseover") ? "highlight" : "normal" } }一个事件处理函数的模板
// shared function function getTargetElement(evt) { var elem if (evt.target) { elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target } else { elem = evt.srcElement } return elem } function functionName(evt) { evt = (evt) ? evt : ((window.event) ? window.event : "") if (evt) { var elem = getTargetElement(evt) if (elem) { // process event here } } }其他关于事件模型的一些资料:
-
- 同时支持三种事件模型(中英文版本)
http://developer.apple.com/internet/webcontent/eventmodels.html
http://developer.apple.com.cn/internet/webcontent/eventmodels.html
-
- Handling events with the DOM – Part I
http://www.devarticles.com/c/a/JavaScript/Handling-events-with-the-DOM-Part-I/
-
- Handling events with the DOM – Part III
http://www.devarticles.com/c/a/JavaScript/Handling-events-with-the-DOM-Part-III/
-
- DOM Design Tricks II
-
- Event handling in the DOM
3、Bubbling Library
Bubbling Library(http://www.bubbling-library.com/)的思想来源于Event-Driven Web Application Design
要使用Bubbling Library的用法,首先还要熟悉YUI Event.
关于Bubbling Library的使用可以其文档及如下资料:
http://yuiblog.com/blog/2007/09/13/bubbling-library-by-caridy/
- 样例
- Bubbling Library的适用场合
- 与jQuery实现机制对比
4、参考资料
Apple中文开发站点的一些文档
http://developer.apple.com.cn/Documentation/InternetWeb/
Pro JavaScript Techniques第六章: 事件
http://bbs.blueidea.com/viewthread.php?tid=2745405&page=1#pid3215727
Learning jQuery
http://www.learningjquery.com/
Yahoo! UI Library: Event Utility
http://developer.yahoo.com/yui/event/
Event Delegation versus Event Handling
http://icant.co.uk/sandbox/eventdelegation/
Unobtrusive Javascript
Technorati 标签: event-driven , yui , javascript , ajax , bubbling-libray , yuiblog , DOM Event model
转载请注明:出家如初,成佛有余 » bubbling-library:YUI Extension for Event-Driven Applications研究