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

28

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

我不想使用像YUI或jQuery这样的第三方库来完成。我的目标是能够发送类似于这样的事件:

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

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

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

请不要使用第三方库的解决方案。


你可以自己构建。非常简单,纯JS,不需要DOM - 在这里查看我的答案:https://stackoverflow.com/questions/31110706/write-a-custom-event-dispatcher-in-javascript/42751577?noredirect=1#answer-42751577 - Jakob Sternberg
6个回答

26

对我有效的一种方法是调用document.createEvent(),进行初始化并使用window.dispatchEvent()进行分发。

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

2
这个支持所有的A级浏览器吗,包括像IE6这样的旧版本? - nil
7
根据Mozilla MDN,这是已弃用的。 - Ajax
1
@Ajax 的链接不再提到弃用。请使用此 MDN 链接:https://developer.mozilla.org/en-US/docs/Web/API/document.createEvent。 - Drew Noakes
1
Mozilla MDN 还提到,IE 不支持替代方案(Event 构造函数)。 - Nilpo

5

我有点晚加入这个派对,但是我在搜寻同样的内容。我不太喜欢上面的第一个答案,因为它依赖文档来管理自定义事件。这很危险,因为它是全局的,如果另一个脚本碰巧依赖于相同的自定义事件,可能会产生冲突。

我发现的最佳解决方案在这里: Nicholas C. Zakas - JavaScript中的自定义事件

不幸的是,由于JavaScript不支持继承关键字,使用原型会有些混乱,但它确实能保持事情井然有序。


1
当使用DOM元素来传递事件时,这非常简单。
给定一个元素:
var element = document.querySelector('div#rocket');

要让客户订阅:

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

然后使用以下代码来分派/触发/激活事件:

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

-1

这是 John 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 );
}

更多相关内容请查看他的博客文章http://ejohn.org/projects/flexible-javascript-events/


1
虽然这段代码肯定很有用,但我认为它并没有解决问题。你可以将事件附加和分离到元素上,但最初的问题是如何创建和发送(分派)自定义事件。 - auco

-1
我正在考虑将支持的处理程序分配给一个新的命名空间,即支持事件的引用。下面的代码可以工作(将其粘贴到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);

这不会分派自定义事件。 - Rick

-3

其实并不难 - 事件定义并不多,只有三个版本。第一个是正确的 (addEventListener),然后是IE的方式 (attachEvent),还有一种兼容旧浏览器的方式 (element.onevent = function)

因此,完整的事件处理解决方案应该像这样:

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;
  }
}

并清除事件:

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;
  }
}

还有一个例子:

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

这并不是一个完整的示例,因为兼容性处理程序总是覆盖先前的事件(它不是追加操作,而是覆盖),所以您可能希望检查是否已经设置了处理程序,然后将其保存到某个临时变量中,并在事件处理程序函数内触发它。


那并没有帮助,我需要一个自定义事件。这意味着就像有 MouseEvent 一样,可以有 CustomEvent。你所做的很好,但不是我要找的解决方案。我需要能够分派事件并随事件发送一些数据。例如,在游戏中,我想要分派一个得分更新事件,我会用事件发送需要添加的分数。 - Josua Pedersen
不是给定问题的答案 - subrat71

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接