js框架开发之旅--事件

这一篇我们将介绍事件的工作原理,和不同的框架中事件的实现方法,以及事件接口的设计。我会在最后选择一种接口的设计,来实现我们的事件功能。


原理

事件和Javascript的关系非常密切,你可以想象如果没有事件,页面怎么和用户进行交互。Javascript一出现的时候,就已经有事件功能了。最早的事件处理时写在html代码里的,如下:
<a href="/" οnclick="alert('Hello World!')">
你之前一定见过这样的写法。它最早出现在Netscape浏览器里,由于Netscape的早期版本如此的受欢迎,微软也实现了与Netscape相兼容的事件。
上面的代码在Javascript代码里是这样的:
// assume 'element' is the previous link minus the onclick
element.onclick = function() { alert('Hello World!'); };


访问事件对象

我们可以用下面方法访问事件对象:
function handler(event) {
    if (!event) var event = window.event;
}
window.event是微软特有的属性,用来记录上一次的事件对象。在一般的程序中,这种做法非常危险,会造成访问冲突。但是Javascript是单线程的,这种方法在Javascript中是安全的可信赖的。
jQuery中是这样做的:
handle: function( event ) {
  var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
  event = args[0] = jQuery.event.fix( event || window.event );


停止事件

我曾经被默认事件和事件冒泡搞的比较乱,我之前一直以为停止一个事件就是把一切都停止了。但是,在这里不是这样的。
默认事件
在一个事件处理方法里返回false可以阻止默认事件:
element.onclick = function() { alert('Hello World!'); return false; };
如果是个a标签,就不会跳到对应的链接了。
捕获和冒泡
如果我们把onclick事件绑定在两个元素上,其中一个是另一个的父节点,我们很难弄清楚哪个方法会优先执行。不同的浏览器有不同的处理方式。然而,幸运的是我们并不经常会遇到这样的问题,我们更多的是去阻止事件传播。
function handler(event) {
    if (!event) var event = window.event;
    event.cancelBubble = true;
    if (event.stopPropagation) event.stopPropagation();
}
到目前为止,据我所知,只有IE使用cancelBubble,大部分都使用 stopPropagation。

jQuery及其他大部分框架都使用类似上面的原理阻止事件冒泡。


绑定多个事件

当涉及到多个事件的绑定,就比单个事件麻烦了:
element.onclick = function() { alert('Hello World!'); return false; };
element.onclick = function() { alert('This was the best example I could think of'; return false; };
上面的例子重新绑定了onclick,而不是添加了一个新的方法。

我们也不能简单的把所有的事件方法都放到同一个方法里调用,因为我将来可能要删除其中的一些方法。


框架的接口设计

事件框架的工作是简化事件的操作,并使之跨平台。我们要做如下的事情:
  • 统一事件名称,如onClick事件应该变成click
  • 简化事件的注册和删除
  • 跨平台的封装event对象
  • 对冒泡的简化
  • 提供跨平台的键盘和鼠标的交互
  • 弥补一些浏览器的不足,如IE的内存泄露

jQuery的事件

jQuery基于W3C标准实现的事件功能,对浏览器的差异(尤其是IE浏览器)进行了封装。
jQuery把事件功能封装到了内部的DOM对象列表上,接口使用非常简单。
$('a').click(function(event) {
  alert('A link has been clicked');
});
上面的代码把click事件绑定到所有的连接上。
  • 通过event.target可以获取事件元素。
  • 如果是冒泡事件,我们可以通过event.currentTarget获取当前元素,或者通过this对象访问。
  • 通过调用event.preventDefault()阻止默认事件
  • 通过调用event.stopPropagation()阻止事件冒泡
  • 通过$('a').unbind('click')删除事件的绑定
  • 通过$('a').trigger('click')触发事件


Dojo

Dojo的事件实现基于函数间的connections,注册事件的方法如下:
dojo.connect(dojo.byId('a#hello'), 'onclick', function(event) {
  alert('Hello World!');
});
dojo保持了原理的事件名称,event和其他框架一样是做过跨浏览器处理的。
dojo使用dojo.disconnect()解除事件绑定,其他方法跟jQuery基本一样。

通过和几个框架比较发现jQuery的事件实现的最漂亮,因此我们下一篇会借鉴jquery的接口设计,实现我们的事件框架。


牧客网--让自由职业变成一个靠谱的工作


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值