YUI事件体系之Y.Event

在介绍了由Y.Do、Y.CustomEvent、Y.EventTarget构建的自定义事件体系后,本篇文章将为大家介绍建立在这一体系之上,YUI对DOM事件的封装——Y.Event。
Y.DOMEventFacade
众所周知,浏览器之间存在大量的不兼容问题,在事件方面尤其如此。Y.DOMEventFacade主要用来处理DOM事件对象的浏览器兼容问题,提供跨浏览器的简洁接口。事实上,我们常在Y.one('.selector').on('click', function (e) {})中使用的e就是Y.DOMEventFacade的实例。
具体来说,兼容处理的属性主要有:
- target,专门处理了target为文本节点的情况,统一为元素节点,方便操作
- relativeTarget,关联目标节点,在mouseover/mouseout等事件中设置
- keyCode/charCode等输入信息
- pageX/clientX等位置信息
兼容处理的方法主要有:
- stopPropagation/stopImmediatePropagation,不支持停止立即传播时,仅能在YUI层面模拟,不会阻止通过原生方法添加的同层回调,即,在YUI监听过el的click事件后,又通过
el.addEventListener('click', nativeCallback)监听,如果在YUI的回调中调用e.stopImmediatePropagation的话,nativeCallback仍然会执行 - preventDefault
另外,为了方便同时停止传播和阻止默认行为,YUI还提供了halt方法。
我们来简单分析下Y.DOMEventFacade的实现:
1 | // 为简化代码,省略了专门针对未实现DOM2 Events规范浏览器中的事件对象兼容性处理(代码在event-base-ie模块) |
Y.Event
Y.Event的主要作用是提供添加、注销DOM事件监听的接口。和我们通常的理解不一样的是,它并不是一个类,而是一个简单的对象。
YUI对DOM事件监听的处理思路大体是:根据节点、事件类型,创建一个Y.CustomEvent对象cewrapper。然后通过原生方法注册事件监听,回调执行cewrapper.fire方法。所有通过YUI添加的事件监听,都注册cewrapper上,从而实现对DOM事件的包装。
我们先来看下如何使用Y.Event添加事件监听:
1 | // 例1 |
当然,也可以使用Y.Event注销事件监听:
1 | // 例2 |
源代码分析
接下来,让我们看看YUI的内部实现吧。
注:为了更容易的看懂代码的核心,我做了适当的简化,感兴趣的朋友可以去看未删节的源码。
1 | var add = function (el, type, fn, capture) { |
通过Y和Node监听事件
YUI3借鉴了jQuery对HTMLElement/HTMLCollection的封装方式,方便进行链式调用,这就是Y.Node。
事件监听是不是可以不用繁琐的使用Y.Event,在Y.Node对象上直接调用呢?当然可以。主要有四个方法:
- NodeInstance.on
- NodeInstance.once
- NodeInstance.after
- NodeInstance.onceAfter
实际上,以上四个方法是通过内部调用Y的对应方法,例如Node.prototype.on内部调用了Y.on,而Y上的对应方法是由于Y本身是一个Y.EventTarget对象才获得的。最终,在Y.EventTarget.prototype.on中调用了Y.Event。
1 | // 例5 |
示例代码
所有示例代码均在GitHub。