如何在Javascript中创建自定义事件类?

时间:2021-10-26 07:03:47

How do I create a custom event class similar to ActionScript? What I mean by that is a class that I can use to fire off my own events, send the necessary data.

如何创建类似于ActionScript的自定义事件类?我的意思是,我可以使用一个类来发起我自己的事件,发送必要的数据。

I don't wanna use third-party libraries like YUI or jQuery to do it. My goal is to be able to send a event that looks like this.

我不想使用像YUI或jQuery这样的第三方库来做到这一点。我的目标是能够发送看起来像这样的事件。

document.addEventListener("customEvent", eventHandler, false);

function eventHandler(e){
    alert(e.para1);
}

document.dispatchEvent(new CustomEvent("customEvent", para1, para2));

Please no third-party library solutions.

请不要第三方库解决方案。

6 个解决方案

#1


26  

A method that worked for me was to call document.createEvent(), init it and dispatch it with window.dispatchEvent().

对我有用的方法是调用document.createEvent(),初始化它并使用window.dispatchEvent()调度它。

  var event = document.createEvent("Event");
  event.initEvent("customEvent", true, true);
  event.customData = getYourCustomData();
  window.dispatchEvent(event);

#2


5  

I'm a little late to the party here, but was searching for the same thing. I'm not keen on the first answer (above) because it relies upon the document to manage the custom event. This is dangerous because it's global and could potentially conflict with another script should that script coincidentally rely on the same custom event.

我在这里参加派对有点晚了,但是正在寻找同样的事情。我并不热衷于第一个答案(上图),因为它依赖于文档来管理自定义事件。这很危险,因为它是全局的,如果该脚本巧合地依赖于同一个自定义事件,则可能与另一个脚本发生冲突。

The best solution I've found is here: Nicholas C. Zakas - Custom Events in Javascript

我发现的最佳解决方案是:Nicholas C. Zakas - Javascript中的自定义事件

Unfortunately, since javascript doesn't support inheritance keywords, it's a bit messy with prototyping, but it definitely keeps things tidy.

不幸的是,由于javascript不支持继承关键字,原型设计有点混乱,但它确实让事情保持整洁。

#3


1  

This is straightforward when using DOM elements to broker the events.

使用DOM元素来代理事件时,这很简单。

Given an element:

给定一个元素:

var element = document.querySelector('div#rocket');

For a client to subscribe:

对于客户订阅:

element.addEventListener('liftoff', function(e)
{
    console.log('We have liftoff!');
});

Then to dispatch/raise/fire the event, use this code:

然后发送/引发/触发事件,使用以下代码:

element.dispatch(new Event('liftoff'));

#4


-1  

This by John Resig:

这是由约翰Resig:

function addEvent( obj, type, fn ) {
  if ( obj.attachEvent ) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
    obj.attachEvent( 'on'+type, obj[type+fn] );
  } else
    obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
  if ( obj.detachEvent ) {
    obj.detachEvent( 'on'+type, obj[type+fn] );
    obj[type+fn] = null;
  } else
    obj.removeEventListener( type, fn, false );
}

More at his blog post at http://ejohn.org/projects/flexible-javascript-events/.

更多信息请访问http://ejohn.org/projects/flexible-javascript-events/。

#5


-1  

I was just thinking of assigning a supported handler to a new namespace i.e. a reference to a supported event. The code below works (paste it in console of Chrome) but you can write it in a better format, and you should have additional helper methods (that can redefine themselves as well), for xBrowser support, and for sniffing support types (which after you've detected which path to use, you'll have the function redefine itself. I hope what I have below helps.

我只想考虑将支持的处理程序分配给新的命名空间,即对支持的事件的引用。下面的代码可以工作(将其粘贴到Chrome的控制台中),但您可以用更好的格式编写它,并且您应该有其他帮助方法(也可以重新定义自己),xBrowser支持以及嗅探支持类型(之后)你已经检测到要使用哪条路径,你将会重新定义自己的功能。我希望下面的内容有所帮助。

var de = document.documentElement || document.getElementsByTagName[0];

function all(){ console.log('all') };

var customEventForSomeSpecificElement = function customEventForSomeSpecificElement() {
    return ({
            customEvent: function() {
                if ('onclick' in de ) {
                    return 'click';
                }
            },
            init: function(){ return this.customEvent(); }
        }).init();
}();

de.addEventListener(customEventForSomeSpecificElement, all, false);

#6


-3  

It's not so hard actually - there isn't so many event definitions, only three versions. The first one is the corect one (addEventListener), then there's the IE way (attachEvent) and then there's the compatibility way for older browser (element.onevent = function)

实际上并不是那么难 - 没有那么多的事件定义,只有三个版本。第一个是corect one(addEventListener),然后是IE方式(attachEvent),然后是旧浏览器的兼容方式(element.onevent = function)

So a complete event handling solution would look something like this:

所以一个完整的事件处理解决方案看起来像这样:

setEvent = function(element, eventName, handler){
  if('addEventListener' in element){
    //W3
    element.addEventListener(eventName,handler,false);
  }else if('attachEvent' in elm){
    //IE
    elm.attachEvent('on'+eventName,handler)
  }else{
    // compatibility
    elm['on'+eventName] = handler;
  }
}

and to clear events:

并清除事件:

clearEvent = function(element, eventName, handler){
  if('removeEventListener' in element){
    //W3
    element.removeEventListener(eventName,handler,false);
  }else if('detachEvent' in elm){
    //IE
    elm.detachEvent('on'+eventName,handler)
  }else{
    // compatibility
    elm['on'+eventName] = null;
  }
}

and an example:

一个例子:

setEvent(document, "click", function(){alert('hello world!');});
clearEvent(document, "click", function(){alert('hello world!');});

This is not really a complete example though since the compatibility handler always overwrites the previous events (it's not appending actions, it's overwriting) so you probably would like to check if a handler is already set and then save it into some temporary variable and fire it inside the event handler function.

这不是一个完整的例子,因为兼容性处理程序总是覆盖以前的事件(它不会附加动作,它会被覆盖)所以你可能想检查一个处理程序是否已经设置然后将它保存到一些临时变量并激活它在事件处理函数内部。

#1


26  

A method that worked for me was to call document.createEvent(), init it and dispatch it with window.dispatchEvent().

对我有用的方法是调用document.createEvent(),初始化它并使用window.dispatchEvent()调度它。

  var event = document.createEvent("Event");
  event.initEvent("customEvent", true, true);
  event.customData = getYourCustomData();
  window.dispatchEvent(event);

#2


5  

I'm a little late to the party here, but was searching for the same thing. I'm not keen on the first answer (above) because it relies upon the document to manage the custom event. This is dangerous because it's global and could potentially conflict with another script should that script coincidentally rely on the same custom event.

我在这里参加派对有点晚了,但是正在寻找同样的事情。我并不热衷于第一个答案(上图),因为它依赖于文档来管理自定义事件。这很危险,因为它是全局的,如果该脚本巧合地依赖于同一个自定义事件,则可能与另一个脚本发生冲突。

The best solution I've found is here: Nicholas C. Zakas - Custom Events in Javascript

我发现的最佳解决方案是:Nicholas C. Zakas - Javascript中的自定义事件

Unfortunately, since javascript doesn't support inheritance keywords, it's a bit messy with prototyping, but it definitely keeps things tidy.

不幸的是,由于javascript不支持继承关键字,原型设计有点混乱,但它确实让事情保持整洁。

#3


1  

This is straightforward when using DOM elements to broker the events.

使用DOM元素来代理事件时,这很简单。

Given an element:

给定一个元素:

var element = document.querySelector('div#rocket');

For a client to subscribe:

对于客户订阅:

element.addEventListener('liftoff', function(e)
{
    console.log('We have liftoff!');
});

Then to dispatch/raise/fire the event, use this code:

然后发送/引发/触发事件,使用以下代码:

element.dispatch(new Event('liftoff'));

#4


-1  

This by John Resig:

这是由约翰Resig:

function addEvent( obj, type, fn ) {
  if ( obj.attachEvent ) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
    obj.attachEvent( 'on'+type, obj[type+fn] );
  } else
    obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
  if ( obj.detachEvent ) {
    obj.detachEvent( 'on'+type, obj[type+fn] );
    obj[type+fn] = null;
  } else
    obj.removeEventListener( type, fn, false );
}

More at his blog post at http://ejohn.org/projects/flexible-javascript-events/.

更多信息请访问http://ejohn.org/projects/flexible-javascript-events/。

#5


-1  

I was just thinking of assigning a supported handler to a new namespace i.e. a reference to a supported event. The code below works (paste it in console of Chrome) but you can write it in a better format, and you should have additional helper methods (that can redefine themselves as well), for xBrowser support, and for sniffing support types (which after you've detected which path to use, you'll have the function redefine itself. I hope what I have below helps.

我只想考虑将支持的处理程序分配给新的命名空间,即对支持的事件的引用。下面的代码可以工作(将其粘贴到Chrome的控制台中),但您可以用更好的格式编写它,并且您应该有其他帮助方法(也可以重新定义自己),xBrowser支持以及嗅探支持类型(之后)你已经检测到要使用哪条路径,你将会重新定义自己的功能。我希望下面的内容有所帮助。

var de = document.documentElement || document.getElementsByTagName[0];

function all(){ console.log('all') };

var customEventForSomeSpecificElement = function customEventForSomeSpecificElement() {
    return ({
            customEvent: function() {
                if ('onclick' in de ) {
                    return 'click';
                }
            },
            init: function(){ return this.customEvent(); }
        }).init();
}();

de.addEventListener(customEventForSomeSpecificElement, all, false);

#6


-3  

It's not so hard actually - there isn't so many event definitions, only three versions. The first one is the corect one (addEventListener), then there's the IE way (attachEvent) and then there's the compatibility way for older browser (element.onevent = function)

实际上并不是那么难 - 没有那么多的事件定义,只有三个版本。第一个是corect one(addEventListener),然后是IE方式(attachEvent),然后是旧浏览器的兼容方式(element.onevent = function)

So a complete event handling solution would look something like this:

所以一个完整的事件处理解决方案看起来像这样:

setEvent = function(element, eventName, handler){
  if('addEventListener' in element){
    //W3
    element.addEventListener(eventName,handler,false);
  }else if('attachEvent' in elm){
    //IE
    elm.attachEvent('on'+eventName,handler)
  }else{
    // compatibility
    elm['on'+eventName] = handler;
  }
}

and to clear events:

并清除事件:

clearEvent = function(element, eventName, handler){
  if('removeEventListener' in element){
    //W3
    element.removeEventListener(eventName,handler,false);
  }else if('detachEvent' in elm){
    //IE
    elm.detachEvent('on'+eventName,handler)
  }else{
    // compatibility
    elm['on'+eventName] = null;
  }
}

and an example:

一个例子:

setEvent(document, "click", function(){alert('hello world!');});
clearEvent(document, "click", function(){alert('hello world!');});

This is not really a complete example though since the compatibility handler always overwrites the previous events (it's not appending actions, it's overwriting) so you probably would like to check if a handler is already set and then save it into some temporary variable and fire it inside the event handler function.

这不是一个完整的例子,因为兼容性处理程序总是覆盖以前的事件(它不会附加动作,它会被覆盖)所以你可能想检查一个处理程序是否已经设置然后将它保存到一些临时变量并激活它在事件处理函数内部。