28

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.

I don't want to 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:

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

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

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

Please no third-party library solutions.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Josua Pedersen
  • 620
  • 1
  • 6
  • 13
  • You can build your own. It's very simple, pure JS and does not require a DOM - check my answer here: https://stackoverflow.com/questions/31110706/write-a-custom-event-dispatcher-in-javascript/42751577?noredirect=1#answer-42751577 – Jakob Sternberg Oct 07 '17 at 14:49

6 Answers6

26

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

  var event = document.createEvent("Event");
  event.initEvent("customEvent", true, true);
  event.customData = getYourCustomData();
  window.dispatchEvent(event);
pfleidi
  • 2,936
  • 3
  • 19
  • 10
  • 2
    does this support all A browsers, including old ones like IE6? – nil Jan 11 '12 at 08:42
  • 6
    This is deprected according [Mozilla MDN](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Events/Creating_and_triggering_events) – Ajax Nov 29 '13 at 10:39
  • 1
    The link from @Ajax doesn't mention deprecation any more. Use this MDN link instead: https://developer.mozilla.org/en-US/docs/Web/API/document.createEvent – Drew Noakes Nov 04 '14 at 10:45
  • 1
    Mozilla MDN also mentions that the alternative (the Event constructor) is not supported by IE. – Nilpo Jan 11 '15 at 01:10
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

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

Rich Hauck
  • 51
  • 1
  • 1
1

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

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'));
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
-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.

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);
WHill
  • 62
  • 4
-1

This by 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 );
}

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

nicholas
  • 14,184
  • 22
  • 82
  • 138
  • 1
    While the code is surely useful, I don't think it helps with the issue. You can attach and detach events to elements, but the original question was how to create and send (dispatch) a custom event. – auco Jan 13 '12 at 15:05
-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)

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.

Andris
  • 27,649
  • 4
  • 34
  • 38
  • That does not help, I need to have a Custom Event. What that means is just like there is a MouseEvent there can be a CustomEvent. What you are doing there is good but not the solution I was looking for. I need to be able to dispatch a event and send some data with the event. For example in a game, I want to dispatch a event for score to get updated I would send the score that is needed to be added with the event. – Josua Pedersen Jan 13 '10 at 23:39
  • Not the answer for the given question – subrat71 Dec 03 '14 at 10:11