673

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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
KoolKabin
  • 17,157
  • 35
  • 107
  • 145
  • 2
    Please change the accepted answer to [this](http://stackoverflow.com/a/20548330/3853934), it's more up-to-date. – Michał Perłakowski Apr 02 '16 at 15:57
  • 2
    @RickyStam It looks like that MDN article [moved to here](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) – styfle Dec 05 '16 at 15:14

19 Answers19

517

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);
}
Alsciende
  • 26,583
  • 9
  • 51
  • 67
  • 6
    Dont't forget that only the IE version has the 'on' in front (I missed that at first) – hugomg Sep 15 '11 at 13:05
  • 50
    What does the variable `eventName` contain here? – NeDark Sep 15 '11 at 19:49
  • @Alsciende how can I attach my event handler to this custom event? – ThemeZ Apr 26 '12 at 08:35
  • `dataavailable` should be in the `eventName` variable I believe. – fearphage Dec 12 '12 at 21:23
  • 1
    Yep dataavailable should be in eventName and memo should be defined too (define to {} is ok). – Charles Jul 05 '13 at 13:18
  • 1
    I think the question is: where does eventName come from? In this code it is undefined. Should it be "dataavailable"? If so, please edit the answer. – B T Aug 27 '13 at 22:22
  • 4
    Internet Explorer 9+ handles createEvent and dispatchEvent, so there is no need for those if statements. – Blake Sep 04 '13 at 19:59
  • 8
    This example doesn't even works, see my answer: http://stackoverflow.com/a/20548330/407213 – Dorian Dec 12 '13 at 16:08
  • I am confused on whether this is a cross-browser technique. Is it? – nicholaswmin May 10 '14 at 15:33
  • fireEvent on IE what verison of IE it supports? – georgelviv May 03 '15 at 14:02
  • 1
    Looks like the process for creating custom events might change at some point - see the [MDN article](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) for more details. But for now this answer worked fine for me, so thanks! – Brendan Nov 03 '15 at 16:48
  • The last lines have to call `document.dispatchEvent` and `document.fireEvent` respectively. – Andreas Haufler Feb 23 '16 at 16:08
  • 1
    `document.createEvent` seems to be deprecated in favor of `new Event`: https://developer.mozilla.org/en-US/docs/Web/API/Document/createEvent – Ciro Santilli OurBigBook.com Jun 01 '16 at 20:32
  • does not work on ie11 via virtualbox on mac host: https://github.com/lingtalfi/browsers-behaviours/blob/master/listeners-execution-order/listeners.md – ling Oct 06 '16 at 06:28
  • or: $(selector).change(); – Andrew Aug 30 '17 at 15:46
  • 1
    @CiroSantilli郝海东冠状病六四事件法轮功 [Document.createEvent()](https://developer.mozilla.org/en-US/docs/Web/API/Document/createEvent) isn’t deprecated, but Event.initEvent() is, see [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent). – jak.b Nov 20 '20 at 18:16
426

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.

Bob Stein
  • 16,271
  • 10
  • 88
  • 101
Dorian
  • 22,759
  • 8
  • 120
  • 116
  • 12
    One thing to add: if there should be a know-typed event (like [TransitionEvent](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent), [ClipboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent), etc) the appropriate constructor could be called. – Kiril Jul 01 '14 at 13:04
  • Won't work with any version of IE (https://caniuse.com/#feat=customevent). See my [answer](https://stackoverflow.com/a/49117631/165673) for a fix. – Yarin Mar 05 '18 at 19:02
  • 4
    Note to future readers, `detail` is a property of the `Event`, so assign any data you want to access at the other end to it and access by `event.detail`. +1 – olfek Feb 29 '20 at 14:26
172

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 }));
svenmeier
  • 5,681
  • 17
  • 22
e18r
  • 7,578
  • 4
  • 45
  • 40
  • 12
    This should be the accepted answer as it doesn't use deprecated methods like initEvent() – user2912903 Feb 10 '19 at 11:28
  • 4
    Nice solution, but be aware this will not work on IE11. You should then use `CustomEvent` and the according polyfill. – Fabian von Ellerts Mar 19 '19 at 14:46
  • 3
    We shouldn't worry about Internet Explorer anymore. Microsoft says it's dead, and so do we. Anyone who still uses IE deserves the dead version of your webpage. – ilsloaoycd Feb 21 '23 at 20:30
52

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.

Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • 5
    The correct syntax is $('#yourElement').trigger('customEventName', [ arg0, arg1, ..., argN ]); You have forgotten the [] at the second parameter – harry Jul 09 '14 at 10:35
30

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>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • 1
    This will not work for any version of IE, as a `window.CustomEvent` exists but it cannot be called as a constructor: http://caniuse.com/#search=CustomEvent ;) – SidOfc Jun 23 '17 at 13:21
15

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);
    }
};
Community
  • 1
  • 1
S.Mishra
  • 3,394
  • 28
  • 20
12

The accepted answer didn’t 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,
}));

Here’s 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

Ming
  • 4,468
  • 1
  • 21
  • 21
9

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

Yarin
  • 173,523
  • 149
  • 402
  • 512
8

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.

chopper
  • 6,649
  • 7
  • 36
  • 53
KWallace
  • 1,570
  • 1
  • 15
  • 25
  • 1
    What if you want to do multiple different things for the same event (or well, callback function in your case) depending on context? :) It's a good alternative but this feels more like a comment than an answer as the OP wants to know how to programmatically trigger an event as opposed to using a callback :) – SidOfc Jun 23 '17 at 13:26
  • You are quite right that this should have been a comment rather than an answer. Why? Because, uhm, well, .... it doesn't answer the question that was actually asked. Good call. As to your own question, I'd say this would be a great opportunity for constructors in JavaScript! ;-) But without them, I'd say, send an argument with your function call and let that be used to determine what the function should do. – KWallace Sep 11 '17 at 21:05
6

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.

Aleksander Lech
  • 1,105
  • 12
  • 16
  • 1
    This does not take into account what kind of event it is. Blurring and focusing may trigger the event but it may not as well. This is inviting bugs. – Mardok Jan 25 '16 at 21:21
  • 1
    This also applies to `element.click()`. – AxeEffect Jun 13 '17 at 10:46
  • This fixed a weird issue for my Angular/Cordova app, in Android, where the textarea would refuse to clear itself. So thanks. – DarkNeuron Jul 11 '17 at 12:22
3
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");
toto
  • 1,180
  • 2
  • 13
  • 30
  • 1
    This is deprecated. Only useful for polyfills. https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent – hipkiss Jan 12 '17 at 16:59
1

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!

Ifeanyi Amadi
  • 776
  • 5
  • 10
1

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

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

var input = document.getElementById("my_input");
var button = document.getElementById("my_button");

input.addEventListener('change', function (e) {
    alert('change event fired');
});
button.addEventListener('click', function (e) {
    input.value = "Bye World";
    input.triggerEvent("change");
});
<input id="my_input" type="input" value="Hellow World">
<button id="my_button">Change Input</button>
iProDev
  • 547
  • 6
  • 5
1

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.

NVRM
  • 11,480
  • 1
  • 88
  • 87
0

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.

Walle Cyril
  • 3,087
  • 4
  • 23
  • 55
0
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'

Dan Alboteanu
  • 9,404
  • 1
  • 52
  • 40
-2

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 
}
Pall Arpad
  • 1,625
  • 16
  • 20
-3

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.

Bhuvan Arora
  • 154
  • 2
  • 13
-11

What you want is something like this:

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

Using jQuery, it would be something like this:

$(".example").trigger("click");
showdev
  • 28,454
  • 37
  • 55
  • 73
  • trigger method is not wrong, but it is a jquery method – Kamuran Sönecek Dec 29 '15 at 08:33
  • 2
    1. `document.getElementByClassName` doesn't exist. 2. `document.getElementsByClassName` exist but returns a list. 3. this only works for a select few native events. 4. The last example triggers a jQuery event where no underlying native event exists. – Glenn Jorde Mar 23 '16 at 08:57