581

I'm setting a date-time textfield value via a calendar widget. Obviously, the calendar widget does something like this :

document.getElementById('datetimetext').value = date_value;

What I want is:
On changing value in the date-time textfield I need to reset some other fields in the page. I've added a onchange event listener to the datetimetext field which is not getting triggered, because I guess onchange gets triggered only when the element gets focus & its value is changed on losing focus.

Hence I'm looking for a way to manually trigger this onchange event (which I guess should take care of checking the value difference in the text field).

Any ideas?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
CodeTweetie
  • 6,075
  • 3
  • 19
  • 23

2 Answers2

618

MDN suggests that there's a much cleaner way of doing this in modern browsers:

// Assuming we're listening for e.g. a 'change' event on `element`

// Create a new 'change' event
var event = new Event('change');

// Dispatch it.
element.dispatchEvent(event);
Milan Iliev
  • 6,546
  • 1
  • 15
  • 13
  • This did not work for me. Are you sure that is not for custom events only? – Brett Zamir Jun 07 '14 at 12:30
  • 97
    @BrettZamir Worked for me (at least in Chrome 36) the following way: `document.querySelector('select.freight').dispatchEvent(new Event('change', { 'bubbles': true }))` – SlimShaggy Aug 06 '14 at 15:10
  • 10
    Just FYI on this... MDN does mention this, but its not supported by IE10+ (arguably also modern by definition of the word modern..) and only in the nightly of Safari (as time of writing) IE10+ does have this constructor method but you need to specify the type of event, eg. MouseEvent or KeyboardEvent :see:- https://msdn.microsoft.com/en-us/library/ie/dn905219%28v=vs.85%29.aspx –  Feb 24 '15 at 03:31
  • @MrJustastic A year later, MDN lists compatibility with MS Edge (the current version of IE, if you ask Microsoft) and Safari 6. On mobile, it lists iOS Safari 6, and I assume Chrome on Android ought to support it too. – Milan Iliev Oct 22 '15 at 16:55
  • 13
    This does not work on IE11 – Joel Jul 11 '16 at 10:49
  • its working great, but too damn slow, why is it? Can anything be done to boost performance of app? – Abhinav May 30 '17 at 11:18
  • @Abhinav what is slow? Is it the method of dispatching itself or the handler code attached to the event? – Milan Iliev May 30 '17 at 15:58
  • @MilanIliev : I think the method of dispatching itself, because the handler code attached to the event executes fast when I use jquery's `trigger()` method. I dont want to use jquery since most part of my app is written in javascript. What can I do to improve the performance? – Abhinav May 31 '17 at 04:57
  • @Abhinav Not sure why this dispatch method would be slower. Can you provide examples of how you're attaching it in both cases (raw JS and jQuery) and also details on what browser(s) is it slow, and how slow? – Milan Iliev May 31 '17 at 14:09
  • @BrettZamir what does the 'bubbles' : true bit do? – Percy Feb 05 '18 at 15:53
  • @Rick : When an event "bubbles" in the DOM (like many built-in events), it means that unless a handler attached to the elements in the bubble chain (starting with the element on which an event is dispatched) stops propagation (as via a call to `event.stopPropagation()`), that element's parent will also be checked for event handlers to fire, with the process repeated until either propagation is stopped or there are no more ancestors (when one is at root). You can get this propagating behavior for events by adding `bubbles: true`. – Brett Zamir Feb 06 '18 at 06:28
  • Stopping propagation is different from `preventDefault` btw which stops default behaviors associated with an element from occurring, such as links being followed or forms being submitted, but it does not stop events being triggered on ancestors. – Brett Zamir Feb 06 '18 at 06:32
  • 8
    `element.dispatchEvent(new window.Event('change', { bubbles: true }))` if you want to bubble too –  Jan 17 '20 at 22:17
  • While using Chrome 80 in February 2020, the expression `document.createEvent('change')` gives me a runtime exception: "The provided event type ('change') is invalid.". – Dai Feb 24 '20 at 12:22
  • 6
    It's `new CustomEvent('change')` now(June 2020/Covid-19). – Mike Mestnik Jun 06 '20 at 00:41
  • 1
    @MikeMestnik Actually the above code (`.dispatchEvent(new Event('change'))`) works just fine for me in FF. – Andrew Oct 31 '20 at 02:14
  • Seriously, it's not as convenient as the .click() event? *facepalm* Trying to determine if dispatchEvent actually supports IE 10+ because it's important to be fully compatible. – Skystrider Sep 20 '21 at 18:42
  • 1
    `new Event('change')` is still valid according to MDN. It just doesn't allow for extra data to be sent? – Brendon Muir Oct 19 '22 at 23:08
  • @MikeMestnik , the prototype inheritance and property descriptors are different. May I ask, why not use "Event" but "CustomEvent" exactly? Related: https://stackoverflow.com/a/40795249/5113030 (*Event vs CustomEvent*...) ; https://www.w3.org/TR/uievents – Artfaith Jul 20 '23 at 09:24
583

There's a couple of ways you can do this. If the onchange listener is a function set via the element.onchange property and you're not bothered about the event object or bubbling/propagation, the easiest method is to just call that function:

element.onchange();

If you need it to simulate the real event in full, or if you set the event via the HTML attribute or addEventListener/attachEvent, you need to do a bit of feature detection to correctly fire the event:

if ("createEvent" in document) {
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent("change", false, true);
    element.dispatchEvent(evt);
}
else
    element.fireEvent("onchange");
Yves M.
  • 29,855
  • 23
  • 108
  • 144
Andy E
  • 338,112
  • 86
  • 474
  • 445
  • 1
    thanks. this works, but am not sure about browser detection here. wondering if there is a way to do the same via YUI library. thanks anyways. – CodeTweetie May 18 '10 at 11:48
  • 1
    Thanks. Seems to be working in Android's WebView with those 3 lines from `else` block. – Kuitsi Apr 30 '13 at 13:38
  • 2
    Andy E, this does not work in IE10, any ideas? – Nick Binnet Jul 23 '13 at 08:43
  • 1
    @NickBinnet: interesting. I'm working in Linux at the moment and can't switch to test for a solution, but I would suggest swapping the `if` and `else` blocks, and testing for `if ('createEvent' in document)` instead. Let me know if this works and I'll update the answer. – Andy E Jul 24 '13 at 11:37
  • 1
    Andy, you are absolutely correct. It works. Could you please add a reference to this answer on the following question. http://stackoverflow.com/questions/17754972/correct-way-to-trigger-change-event-of-cascadingdropdown-using-jquery – Nick Binnet Jul 24 '13 at 13:33
  • I have a onchange event into a HTML element and `element.onchange();` worked – Marcelo Assis Aug 11 '14 at 18:39
  • This will also work - $("#element").trigger('change'); // make sure you define onchange function above this call – Disha Goyal Aug 21 '14 at 05:39
  • 1
    I only see onchange() not work when using addEvent/attachEvent http://jsfiddle.net/mplungjan/s11uakx7/ – mplungjan Jan 30 '15 at 10:18
  • its working great, but too damn slow, why is it? Can anything be done to boost performance of app? – Abhinav May 30 '17 at 11:18
  • this worked for me for an event defined in jQuery – Will Hardwick-Smith Apr 19 '18 at 23:17
  • @AndyE `Event.initEvent()` is deprecated. [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent) It is recomended to use the `Event()` constructor instead. – davidhartman00 Oct 02 '19 at 22:22
  • 8
    This is "The old-fashioned way". Now there is [another way](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events#Creating_custom_events). See Milan answer. – csr-nontol Apr 22 '20 at 21:22
  • "element.onchange is not a function" in latest chrome – OZZIE Apr 26 '22 at 15:26