日期:2014-05-16  浏览次数:20418 次

Javascript事件模型系列(四)我所理解的javascript自定义事件

  被我拖延了将近一个月的javascript事件模型系 列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情,公司的个人的,搞的自己心烦意乱浮躁 了一段时间,好在最近这些事情都一件件趋于平息,我也有了精力继续写文章。

  这个自定义事件其实是挺让我纠结的,首先自己平时从未使用过,只是有一次遇到一个问题有人指点说可以用自定义事件,才对这个东西有了印象。在网上搜“javascript自定义事件”,发现也有不少文章在写,不过说实话让我佩服的却一篇也没找到,就连张鑫旭大哥写的漫谈javascript自定义事件也 把我看的云里雾里。陆续查阅了一些资料后越发觉得自定义事件这个东西真是个鸡肋,没什么用武之地。这也使我一度想放弃写这篇文章,但后来自己又进行了一些 思考,并有了一些新的想法,所以在此还是写出来与大家分享。本来想大手一挥书写标题“javascript自定义事件”,转而一想这个标题真是被用滥了, 满大街走的都是长一个样的,谁能认得我呀,亲,我跟他们可真的不太一样哦。所以前面加上了“我所理解的”,并不全是为标题突出,其实真的有很多自己的理 解。

一、什么是自定义事件

  这个其实并不难理解,js中有很多的事件,如click(单击)、dbclick(双击)、mouseover(鼠标移上)等等,大部分是一些 鼠标或键盘事件,当然也还有其他的如文档的load,只不过我们平时更加关注前者,因为毕竟是要和用户打交道嘛,这些可以统称为DOM事件(都是发生在 DOM元素上)。何为自定义DOM事件呢?举个栗子:元素有单击、双击事件,我现在想定义一个三击事件,即元素被连续点击了三次,就给它起名字叫 tripleclick。这就是一个自定义的事件。再来个栗子:元素的内部html发生变化,我想监听到此事件,于是可以定义一个htmlchange事 件。概念就是这么回事。

  既然有DOM事件,那有没有非DOM事件呢?动脑筋想一想。有了~前段时间刚好研究过history API,其中点击了浏览器后退按钮会触发popstate事件,这就是个非DOM事件。那我们可以自定义些什么非DOM事件呢?再开阔一下思 维,javascript好歹也是一门编程语言呀,除了操作DOM、BOM之外还有很多事情可以做呢。比如我写了一个dog对象,也可以给它自定义个事件 bark(狗叫),一旦发生了这个事件,我们可以捕捉到,在onbark处理函数中执行一些操作,如把dog给赶走。

  那么,所谓自定义事件就是起个名字?这就完了?先埋个伏笔,后面来谈谈我的看法。

二、如何自定义事件

  关于实现自定义事件的方式,我搜索中文的网页大概也就两种方式,而且就是那么几篇文章被抄来抄去,实在是乏味。总结一下:

  第一种方式是自己模拟一个事件结构,其原理是这样的,我们平时监听事件的时候其实就是一种观察者模式,举个例子吧更明确些。

<input type="button" value="点我" onclick="clickhandler()" />
<script type="text/javascript">
function clickhandler(){
    alert('点你怎么了!');
}
</script>

  在这里被观察的主体就是这个button,有一个handler订阅了它的点击事件,当被点击时,button会发布自己被点击的消息,handler接收到消息便开始执行处理函数。是相当标准的一个观察者模式。

  照着这个思路,我们可以把整个过程用代码模拟出来,而不使用浏览器的事件机制,让这个button发布一点其他的消息,比如我们霸气的“三 击”,然后写一个handler来监听这个三击事件即可。具体的实现例子我就不写了,因为我觉得这个模拟的办法简直是太土了,根本拿不上台面,想研究的可 以看下这篇文章http://www.jb51.net/article/33697.htm 尽管我很恶心脚本之家这种随便剽窃别人文章的行为,但抱歉我真的找不到出处了。。。

  看过了第一种土的掉渣的方式,我们再来看看高端洋气的写法。说白了,其实w3c已经定义了标准的自定义事件写法了。

  第二种方式如下:

复制代码
var e = document.createEvent('Event');//创建一个Event对象e
e.initEvent('myevent',true,true);//进行事件初始化
var d1 = document.getElementById('d1');//获取DOM元素
d1.addEventListener('myevent',function(event){
    alert(‘我监听到了自定义事件’+event.type);
},