javascript

events

dom-events

addeventlistener

triggers

I have attached an event to a text box using addEventListener. It works fine. My problem arose when I wanted to trigger the event programmatically from another function.

How can I do it?

Solution 1

Note: the initEvent method is now deprecated. Other answers feature up-to-date and recommended practice.


You can use fireEvent on IE 8 or lower, and W3C's dispatchEvent on most other browsers. To create the event you want to fire, you can use either createEvent or createEventObject depending on the browser.

Here is a self-explanatory piece of code (from prototype) that fires an event dataavailable on an element:

var event; // The custom event that will be created
if(document.createEvent){
    event = document.createEvent("HTMLEvents");
    event.initEvent("dataavailable", true, true);
    event.eventName = "dataavailable";
    element.dispatchEvent(event);
} else {
    event = document.createEventObject();
    event.eventName = "dataavailable";
    event.eventType = "dataavailable";
    element.fireEvent("on" + event.eventType, event);
}

Solution 2

A working example:

// Add an event listener
document.addEventListener("name-of-event", function(e) {
  console.log(e.detail); // Prints "Example of an event"
});

// Create the event
var event = new CustomEvent("name-of-event", { "detail": "Example of an event" });

// Dispatch/Trigger/Fire the event
document.dispatchEvent(event);

For older browsers polyfill and more complex examples, see MDN docs.

See support tables for EventTarget.dispatchEvent and CustomEvent.

Solution 3

If you don't want to use jQuery and aren't especially concerned about backwards compatibility, just use:

let element = document.getElementById(id);
element.dispatchEvent(new Event("change")); // or whatever the event type might be

See the documentation here and here.

EDIT: Depending on your setup you might want to add bubbles: true:

let element = document.getElementById(id);
element.dispatchEvent(new Event('change', { 'bubbles': true }));

Solution 4

if you use jQuery, you can simple do

$('#yourElement').trigger('customEventName', [arg0, arg1, ..., argN]);

and handle it with

$('#yourElement').on('customEventName',
   function (objectEvent, [arg0, arg1, ..., argN]){
       alert ("customEventName");
});

where "[arg0, arg1, ..., argN]" means that these args are optional.

Solution 5

Note: the initCustomEvent method is now deprecated. Other answers feature up-to-date and recommended practice.


If you are supporting IE9+ the you can use the following. The same concept is incorporated in You Might Not Need jQuery.

function addEventListener(el, eventName, handler) {
  if (el.addEventListener) {
    el.addEventListener(eventName, handler);
  } else {
    el.attachEvent('on' + eventName, function() {
      handler.call(el);
    });
  }
}

function triggerEvent(el, eventName, options) {
  var event;
  if (window.CustomEvent) {
    event = new CustomEvent(eventName, options);
  } else {
    event = document.createEvent('CustomEvent');
    event.initCustomEvent(eventName, true, true, options);
  }
  el.dispatchEvent(event);
}

// Add an event listener.
addEventListener(document, 'customChangeEvent', function(e) {
  document.body.innerHTML = e.detail;
});

// Trigger the event.
triggerEvent(document, 'customChangeEvent', {
  detail: 'Display on trigger...'
});


If you are already using jQuery, here is the jQuery version of the code above.

$(function() {
  // Add an event listener.
  $(document).on('customChangeEvent', function(e, opts) {
    $('body').html(opts.detail);
  });

  // Trigger the event.
  $(document).trigger('customChangeEvent', {
    detail: 'Display on trigger...'
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Solution 6

I searched for firing click, mousedown and mouseup event on mouseover using JavaScript. I found an answer provided by Juan Mendes. For the answer click here.

Click here is the live demo and below is the code:

function fireEvent(node, eventName) {
    // Make sure we use the ownerDocument from the provided node to avoid cross-window problems
    var doc;
    if (node.ownerDocument) {
        doc = node.ownerDocument;
    } else if (node.nodeType == 9) {
        // the node may be the document itself, nodeType 9 = DOCUMENT_NODE
        doc = node;
    } else {
        throw new Error("Invalid node passed to fireEvent: " + node.id);
    }

    if (node.dispatchEvent) {
        // Gecko-style approach (now the standard) takes more work
        var eventClass = "";

        // Different events have different event classes.
        // If this switch statement can't map an eventName to an eventClass,
        // the event firing is going to fail.
        switch (eventName) {
        case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
        case "mousedown":
        case "mouseup":
            eventClass = "MouseEvents";
            break;

        case "focus":
        case "change":
        case "blur":
        case "select":
            eventClass = "HTMLEvents";
            break;

        default:
            throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
            break;
        }
        var event = doc.createEvent(eventClass);

        var bubbles = eventName == "change" ? false : true;
        event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable.

        event.synthetic = true; // allow detection of synthetic events
        // The second parameter says go ahead with the default action
        node.dispatchEvent(event, true);
    } else if (node.fireEvent) {
        // IE-old school style
        var event = doc.createEventObject();
        event.synthetic = true; // allow detection of synthetic events
        node.fireEvent("on" + eventName, event);
    }
};

Solution 7

The accepted answer didnt work for me, none of the createEvent ones did.

What worked for me in the end was:

targetElement.dispatchEvent(
    new MouseEvent('click', {
        bubbles: true,
        cancelable: true,
        view: window,
}));

Heres a snippet:

const clickBtn = document.querySelector('.clickme');
const viaBtn = document.querySelector('.viame');

viaBtn.addEventListener('click', function(event) {
    clickBtn.dispatchEvent(
        new MouseEvent('click', {
            bubbles: true,
            cancelable: true,
            view: window,
    }));
});

clickBtn.addEventListener('click', function(event) {
    console.warn(`I was accessed via the other button! A ${event.type} occurred!`);
});
<button class="clickme">Click me</button>

<button class="viame">Via me</button>

From reading: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent

Solution 8

Modified @Dorian's answer to work with IE:

document.addEventListener("my_event", function(e) {
  console.log(e.detail);
});

var detail = 'Event fired';

try {

    // For modern browsers except IE:
    var event = new CustomEvent('my_event', {detail:detail});

} catch(err) {

  // If IE 11 (or 10 or 9...?) do it this way:

    // Create the event.
    var event = document.createEvent('Event');
    // Define that the event name is 'build'.
    event.initEvent('my_event', true, true);
    event.detail = detail;

}

// Dispatch/Trigger/Fire the event
document.dispatchEvent(event);

FIDDLE: https://jsfiddle.net/z6zom9d0/1/

SEE ALSO:
https://caniuse.com/#feat=customevent

Solution 9

Just to suggest an alternative that does not involve the need to manually invoke a listener event:

Whatever your event listener does, move it into a function and call that function from the event listener.

Then, you can also call that function anywhere else that you need to accomplish the same thing that the event does when it fires.

I find this less "code intensive" and easier to read.

Solution 10

I just used the following (seems to be much simpler):

element.blur();
element.focus();

In this case the event is triggered only if value was really changed just as you would trigger it by normal focus locus lost performed by user.

Solution 11

function fireMouseEvent(obj, evtName) {
    if (obj.dispatchEvent) {
        //var event = new Event(evtName);
        var event = document.createEvent("MouseEvents");
        event.initMouseEvent(evtName, true, true, window,
                0, 0, 0, 0, 0, false, false, false, false, 0, null);
        obj.dispatchEvent(event);
    } else if (obj.fireEvent) {
        event = document.createEventObject();
        event.button = 1;
        obj.fireEvent("on" + evtName, event);
        obj.fireEvent(evtName);
    } else {
        obj[evtName]();
    }
}

var obj = document.getElementById("......");
fireMouseEvent(obj, "click");

Solution 12

You could use this function i compiled together.

if (!Element.prototype.trigger)
  {
    Element.prototype.trigger = function(event)
    {
        var ev;

        try
        {
            if (this.dispatchEvent && CustomEvent)
            {
                ev = new CustomEvent(event, {detail : event + ' fired!'});
                this.dispatchEvent(ev);
            }
            else
            {
                throw "CustomEvent Not supported";
            }
        }
        catch(e)
        {
            if (document.createEvent)
            {
                ev = document.createEvent('HTMLEvents');
                ev.initEvent(event, true, true);

                this.dispatchEvent(event);
            }
            else
            {
                ev = document.createEventObject();
                ev.eventType = event;
                this.fireEvent('on'+event.eventType, event);
            }
        }
    }
  }

Trigger an event below:

var dest = document.querySelector('#mapbox-directions-destination-input');
dest.trigger('focus');

Watch Event:

dest.addEventListener('focus', function(e){
   console.log(e);
});

Hope this helps!

Solution 13

You can use below code to fire event using Element method:

if (!Element.prototype.triggerEvent) {
    Element.prototype.triggerEvent = function (eventName) {
        var event;

        if (document.createEvent) {
            event = document.createEvent("HTMLEvents");
            event.initEvent(eventName, true, true);
        } else {
            event = document.createEventObject();
            event.eventType = eventName;
        }

        event.eventName = eventName;

        if (document.createEvent) {
            this.dispatchEvent(event);
        } else {
            this.fireEvent("on" + event.eventType, event);
        }
    };
}

Solution 14

The most efficient way is to call the very same function that has been registered with addEventListener directly.

You can also trigger a fake event with CustomEvent and co.

Finally some elements such as <input type="file"> support a .click() method.

Solution 15

var btn = document.getElementById('btn-test');
var event = new Event(null);

event.initEvent('beforeinstallprompt', true, true);
btn.addEventListener('beforeinstallprompt', null, false);
btn.dispatchEvent(event);

this will imediattely trigger an event 'beforeinstallprompt'

Solution 16

What's worth noticing, is the fact that we can create, any kind of pre-defined events, and listen to it from anywhere.

We are not limited to classical built-in events.

In this base example, a custom event interfacebuiltsuccessuserdefinedevent is dispatched every 3 seconds, on the self.document

self.document.addEventListener('interfacebuiltsuccessuserdefinedevent', () => console.log("WOW"), false)

setInterval(() => {  // Test
  self.document.dispatchEvent(new Event('interfacebuiltsuccessuserdefinedevent')) 
}, 3000 ) // Test

Interesting fact: elements can listen for events that haven't been created yet.

Solution 17

HTML

<a href="demoLink" id="myLink"> myLink </a>
<button onclick="fireLink(event)"> Call My Link </button>

JS

// click event listener of the link element --------------  
document.getElementById('myLink').addEventListener("click", callLink);
function callLink(e) {
    // code to fire
}

// function invoked by the button element ----------------
function fireLink(event) {                   
    document.getElementById('myLink').click();      // script calls the "click" event of the link element 
}

Solution 18

Use jquery event call. Write the below line where you want to trigger onChange of any element.

$("#element_id").change();

element_id is the ID of the element whose onChange you want to trigger.

Avoid the use of

 element.fireEvent("onchange");

Because it has very less support. Refer this document for its support.

Solution 19

What you want is something like this:

document.getElementByClassName("example").click();

Using jQuery, it would be something like this:

$(".example").trigger("click");