Javascript中的自定义事件工作笔记

什么是自定义事件

自定义事件常伴左右,但是我们可能用得很少,我们可以看看jQuery的用法:

 代码如下 复制代码
// 监听自定义事件
$node.on(CUSTOM_EVENT_NAME, callbackFn);
// 触发自定义事件
$node.trigger(CUSTOM_EVENT_NAME, params);
// 解除自定义事件
$node.off(CUSTOM_EVENT_NAME, fn);

看到这里,我们会发现,这个跟我们常用那些个浏览器事件用法几乎一样,只是多了个触发的方法。
那我们应该怎么去理解自定义事件呢?

实现

让我们来看看真实的自定义事件的实现,这样一来就很容易理解自定义事件了。
首先,有个事件对象,我们叫Events = {};。

事件监听

每次事件监听(或者说注册),比如$node.on(EVT_NAME, evtFn);,对应的其实是对事件对象做了这么一个处理:Events[EVT_NAME] = [evtFn];
相当于是给事件对象增加了一个key值和对应存放回调函数的数组对象。

事件解除

而解除自定义事件,其实是做了跟事件监听相反的操作。你增我删。

事件触发

最后是事件触发。
事件触发相当于,把存放的回调函数的数组对象按先后顺序执行了一遍。

实现代码

“通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率。”。相信C#程序员对事件的好处是深有体会的。好了,Code is cheap.看代码:

 代码如下 复制代码
function class1() { // 最简单的事件设计模式
}
class1.prototype = {
show: function () {
this .onShow();
},
onShow: function () { }
}
function test() {
var obj = new class1();
obj.onShow = function () {
alert( " test " );
}
obj.show();
}

下面看看如何给事件处理程序传递参数:

 代码如下 复制代码
// 将有参数的函数封装为无参数的函数
function createFunction(obj, strFunc) {
var args = []; // 定义args 用于存储传递给事件处理程序的参数
if ( ! obj) obj = window; // 如果是全局函数则obj=window;
// 得到传递给事件处理程序的参数
for ( var i = 2 ; i < arguments.length; i ++ ) args.push(arguments[i]);
// 用无参数函数封装事件处理程序的调用
return function () {
obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序
}
}
function class1() {
}
class1.prototype = {
show: function () {
this .onShow();
},
onShow: function () { }
}
function objOnShow(userName) {
alert( " hello, " + userName);
}
function test() {
var obj = new class1();
var userName = " test " ;
obj.onShow = createFunction( null , " objOnShow " , userName);
obj.show();
}

"因为事件机制仅传递一个函数的名称,不带有任何参数的信息,所以无法传递参数进去",这是后话了,“要解决这个问题,可以从相反的思路去考虑,不考虑怎么把参数传进去,而是考虑如何构建一个无需参数的事件处理程序,该程序是根据有参数的事件处理程序创建的,是一个外层的封装。”,这里的“该程序”就是 createFunction函数,它巧妙地利用apply函数将带参数的函数封装为无参数函数。最后我们看看如何实现自定义事件的多绑定:

 代码如下 复制代码
// 使自定义事件支持多绑定
// 将有参数的函数封装为无参数的函数
function createFunction(obj, strFunc) {
var args = []; // 定义args 用于存储传递给事件处理程序的参数
if ( ! obj) obj = window; // 如果是全局函数则obj=window;
// 得到传递给事件处理程序的参数
for ( var i = 2 ; i < arguments.length; i ++ ) args.push(arguments[i]);
// 用无参数函数封装事件处理程序的调用
return function () {
obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序
}
}
function class1() {
}
class1.prototype = {
show: function () {
if ( this .onShow) {
for ( var i = 0 ; i < this .onShow.length; i ++ ) {
this .onShow[i]();
}
}
},
attachOnShow: function (_eHandler) {
if ( ! this .onShow) { this .onShow = []; }
this .onShow.push(_eHandler);
}
}
function objOnShow(userName) {
alert( " hello, " + userName);
}
function objOnShow2(testName) {
alert( " show: " + testName);
}
function test() {
var obj = new class1();
var userName = " your name " ;
obj.attachOnShow(createFunction( null , " objOnShow " , userName));
obj.attachOnShow(createFunction( null , " objOnShow2 " , " test message " ));
obj.show();
}

我们看到,attachOnShow方法实现的基本思想是对数组的push操作,其实我们还可以在事件执行完成之后,移除事件处理函数,下面单独实现:

 代码如下 复制代码
var event = document.createEvent(type);

type: 可以是DOM Level 2中的 HTMLEvents 也可以是 DOM Level 3中的 MouseEvent
可参考 https://developer.mozilla.org/en/DOM/document.createEvent

2) 初始化事件

event.initEvent(type, bubbles, cancelable);
type: 自定义事件的名称
bubbles: 是否冒泡
cancelable: 是否可取消

3) 侦听事件

target.addEventListener(type, listener, useCapture);
type:初始化时注册的事件名称
listener:一般为事件触发的所要执行的function
useCapture指出事件在冒泡还是捕获阶段执行

可参考 https://developer.mozilla.org/en/DOM/element.addEventListener

4) 派发事件

 代码如下 复制代码

bool = element.dispatchEvent(event);
手动派发此事件,即可触发3中的listener 函数

一个完整的例子:

// create the event 
var evt = document.createEvent('Event'); 
// define that the event name is `build` 
evt.initEvent('build', true, true); 
 
// elem is any element 
elem.dispatchEvent(evt); 
 
 
 
// later on.. binding to that event 
// we'll bind to the document for the event delegation style.  
document.addEventListener('build', function(e){ 
  // e.target matches the elem from above 
}, false);

还有一个利用自定义事件模拟点击

 

 代码如下 复制代码

// 将有参数的函数封装为无参数的函数
function createFunction(obj, strFunc) {
var args = []; // 定义args 用于存储传递给事件处理程序的参数
if ( ! obj) obj = window; // 如果是全局函数则obj=window;
// 得到传递给事件处理程序的参数
for ( var i = 2 ; i < arguments.length; i ++ ) args.push(arguments[i]);
// 用无参数函数封装事件处理程序的调用
return function () {
obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序
}
}
function class1() {
}
class1.prototype = {
show: function () {
if ( this .onShow) {
for ( var i = 0 ; i < this .onShow.length; i ++ ) {
this .onShow[i]();
}
}
},
attachOnShow: function (_eHandler) { // 附加事件
if ( ! this .onShow) { this .onShow = []; }
this .onShow.push(_eHandler);
},
detachOnShow: function (_eHandler) { // 移除事件
if ( ! this .onShow) { this .onShow = []; }
this .onShow.pop(_eHandler);
}
}

function objOnShow(userName) {
alert( " hello, " + userName);
}
function objOnShow2(testName) {
alert( " show: " + testName);
}
function test() {
var obj = new class1();
var userName = " your name " ;
obj.attachOnShow(createFunction( null , " objOnShow " , userName));
obj.attachOnShow(createFunction( null , " objOnShow2 " , " test message " ));
obj.show();
obj.detachOnShow(createFunction( null , " objOnShow " , userName));
obj.show(); // 移除一个,显示剩余的一个
obj.detachOnShow(createFunction( null , " objOnShow2 " , " test message " ));
obj.show(); // 两个都移除,一个也不显示
}

1)创建事件

 

时间: 2024-10-26 17:02:32

Javascript中的自定义事件工作笔记的相关文章

详解JavaScript中的自定义事件编写_基础知识

我们可以自定义事件来实现更灵活的开发,事件用好了可以是一件很强大的工具,基于事件的开发有很多优势(后面介绍). 与自定义事件的函数有 Event.CustomEvent 和 dispatchEvent. 直接自定义事件,使用 Event 构造函数: var event = new Event('build'); // Listen for the event. elem.addEventListener('build', function (e) { ... }, false); // Disp

浅谈javascript中this在事件中的应用

 这篇文章主要介绍了浅谈javascript中this在事件中的应用实例,非常有助于我们对this关键字的理解,这里推荐给大家.     this关键字在javascript中是非常强大的,但是如果你不清楚它是怎么工作的就很难使用它.   代码如下: function dosomething(){ this.style.color="#fff"; }   上面这段代码中的this指向什么呢,运行dosomething()会输出什么呢? 在javascript中,this总是指向当前执行

解析javascript中鼠标滚轮事件

  这篇文章主要给大家详细介绍了javascript中鼠标滚轮事件,图文并茂,十分的详细,有需要的小伙伴可以参考下. 所有的现代浏览器都支持鼠标滚轮,并且在用户滚动滚轮时触发时间.浏览器通常使用鼠标滚轮滚动或缩放文档,但可以通过取消mousewheel事件来阻止这些默认操作.有一些互用性问题影响滚轮事件,但是编写跨平台的代码依旧可以行.除了Firefox之外的所有浏览器都支持"mousewheel"事件,但Firefox使用"DOMMouseScroll",而3级D

C# 中如何自定义事件?

C# 中如何自定义事件? Wason (zhuhai) 本次只用一个实例,来说明在C#中如何使用自定义事件.写一个类,此类包含了自定义事件: onSendMsg.文件名:ChatServer.cs public class ChatServer { public delegate void MyEventHandler(string msg); public event MyEventHandler onSendMsg; public void SendMsg() { onSendMsg("开始

Flash/Flex学习笔记(34):AS3中的自定义事件

类似C#中自定义事件需要一个自定义的EventArgs子类一样,AS3也需要开发者自定义一个Event类的子类,这里我们假设一种场景:设计一个Person(人物)类,里面有Age(年龄),Name(姓名),我们希望每当Person类的实例Age(年纪)发生变化时,能触发一些自定义事件,从而调用某些特定的处理方法. 1.先设计Event类的子类AgeChangeEvent package { import flash.events.Event; public class AgeChangeEven

浅谈javascript中this在事件中的应用_javascript技巧

this关键字在javascript中是非常强大的,但是如果你不清楚它是怎么工作的就很难使用它. 复制代码 代码如下: function dosomething(){ this.style.color="#fff"; } 上面这段代码中的this指向什么呢,运行dosomething()会输出什么呢? 在javascript中,this总是指向当前执行的这个函数,或者把函数作为方法调用的这个对象.当我们在页面上定义dosomething()这个方法后,this的所有者就是当前的页面,或

Javascript中活用事件触发对象动作

现在基本上我很少在对象里面写事情触发行为了,因为感觉那样做相同的对象代码利用率太低,容易导致代码冗余. 从学习W3C标准以来,对于代码我好像养成了一种怪癖,能统一复用的,就不会多写一点东西,这样前台页面代码看起来会清爽很多,而效率也会成直线上升. 下面来讲一下最近一个项目里面比较有代表性的东西. (实例可以查看这里http://www.pplive.com/zh-cn/view.html) 程序代码 <script type="text/javascript"> <!

javascript中window.event事件用法详解_基础知识

前两天写程序时因为要用到javascript中的window.event事件,于是就在网上搜了一下,终于找到一篇不错的文章,来与大家分享下: 描述 event代表事件的状态,例如触发event对象的元素.鼠标的位置及状态.按下的键等等. event对象只在事件发生的过程中才有效. event的某些属性只对特定的事件有意义.比如,fromElement 和 toElement 属性只对 onmouseover 和 onmouseout 事件有意义. 例子下面的例子检查鼠标是否在链接上单击,并且,如

asp.net中c#自定义事件的方法和步骤

通常C#自定义事件有下面的几个步骤: 1.声明一个delegate: (用于事件的类型的定义) 如: public delegate void 事件名称EventHandler(object serder, EventArgs e);   //事件名称用你的自己的来代替,随后的EventHandler是C#的建议命名规范,当然如果你不想遵守,可以使用任何字符甚至可以不要. 如果你想自定义事件的参数EventArgs,你可以从这个类派生你自己的事件参数类,然后在delegate的声明中,用你的参数