Amin Jafari Amin Jafari - 5 months ago 19
Javascript Question

Define custom event

I wanna learn how to define a custom event, but not exactly as it is said over the net! let me illustrate:

In the jQuery Website in the part Introducing Custom Events it teaches you how to create a custom event in your code:

e.g.

$(document).on('myEvent',function(){
alert('Hello World');
});


then on an event, you'll call:

$(document).trigger('myEvent');


Well, no problem until here. to go further I have to give you another example:

The Question:

let's say we've defined:

$.fn.myEvent=function(callback){
$(document).bind('contextmenu',this,callback);
};


so we can use it as:

$(document).myEvent(function(){
alert('Hello World');
});


my question here is, how can we define "myEvent" so that we can use it as:

$(document).on('myEvent',function(){
alert('Hello World');
});


with the functionality of the
$(document).myEvent();
so that we can pass a callback function to it without needing to actually
trigger
the event?

More Explanation:

for example, when we call
$(document).on('click');
we don't actually need to trigger the click event elsewhere like
$(document).trigger('click')
in order to get it to work, so whenever
click
happens the function fires. I wanna have an event listener for "myEvent" so that when the conditions are matched, the function fires.

In another word (as mentioned below in the comments), I wanna know if there's a way to let jQuery treat "myEvent" as if it is one of the default events (click, mousemove, submit, etc).

Any answer or idea is highly appreciated.

Answer

For people who are wondering (like I did in the last 2 years) you can create a custom event (using pure javascript) as explained below:

var myEvent = new Event('myEvent');

and then you can use it like this:

document.querySelector('button').addEventListener(myEvent, function () {});

Simple Usage Example DEMO

Let's say we have a variable called bgColor and we want to change background color of 5 buttons, color of a paragraph and border color of an input anytime the bgColor value changes AND we don't want to use an interval to check on the value change and we also don't want to repeat the same code over and over again anytime the variable changes.

First we need to define our variables:

var bgColor='red',
    eventName = 'bgColorChanged';

Then we need to listen for the event:

function Listen(elems,eventName,callback){

    var event=new Event(eventName); //create the custom event

    for(var i=0, elemsLength=elems.length; i < elemsLength; i++){ //iterate over the selected elements

        elems[i].addEventListener(event,callback); //add event listener for our custom event

        elems[i][eventName]=event; //store the event

        //store the element
        if(window.affectedElems){
            window.affectedElems.push(elems[i])
        }
        else{
            window.affectedElems=[];
            window.affectedElems.push(elems[i])
        }
        //----------------------------

    }
}

Now we can listen for our custom event like this:

Listen(document.querySelectorAll('button'),eventName,function(){
    this.style.backgroundColor=bgColor;
});

Then we need a function to Dispatch/Fire our Event:

function dispatchEvent(eventName) {

    var event=document.createEvent("HTMLEvents"), //defining the type of the event

    elems=window.affectedElems; //getting the stored elements

    //iterating over each element and dispatching the stored event
    for(var i=0, elemsLength=elems.length; i < elemsLength; i++){
        event.initEvent(elems[i][eventName], true, true);
        event.eventName = eventName;
        elems[i].dispatchEvent(event);
    }
    //-----------------------------------
}

Now we can fire our event like this:

dispatchEvent(eventName);

Now that everything's ready we just need to change the value of bgColor and just fire the event and let our system do the work.

bgColor='blue';
dispatchEvent(eventName);