Fixed - addEventListener 'change' not working

Issues with the 'change' event not working with addEventListener? I list common issues that might be preventing your code from running as expected and give fixes.

Jul 2, 2023 | Read time 9 minutes

🔔 Table of contents

Introduction

Usually when the addEventListener ‘change’ is not working - it comes down to targeting the wrong element or that you are not using the correct syntax.

It also could be that you are not using the right event type - so instead of “change” event, another event type could be more suitable like ‘keyup’.

A checklist to things to lookout for includes:

  1. Check that the DOM is fully loaded
  2. Check the HTML element is supported
  3. Make sure the element exists
  4. Check that you are using addEventListener correctly
  5. Review other events
  6. Fix other Javascript errors on the page
  7. addEventListener vs dispatchEvent

1. Check that the DOM is fully loaded

Make sure the DOM is fully loaded before attaching event listeners: The element you’re trying to attach the event listener to might not exist at the time your script runs. To prevent this, you can place your script at the end of the body tag, or use DOMContentLoaded event like this:

  

document.addEventListener('DOMContentLoaded', function() {
  var element = document.getElementById('myElement');
  element.addEventListener('change', function() {
    console.log('Change event triggered');
  });
});

2. Check the HTML element is supported

One thing that can trip you up is that the “change” event works only on HTML elements:

  • <input>,
  • <select>, and
  • <textarea> elements.

It won’t work for other elements. If you’re trying to detect changes on other types of elements, you may need to use different event types (like ‘click’, ‘keydown’, etc.).

Now another thing to remember is that depending on the type of element and the user’s interaction with it, the event fires at different times.

Let’s break down a few scenarios:

  • Firstly, the “change” event is triggered when an <input type="checkbox"> element is either checked or unchecked. This could be done via a mouse click or a keyboard action.

It is different for <input type="radio"> elements.

The “change” event is fired when an option is selected, but interestingly not when it’s deselected.

Additionally the change event will trigger AFTER the user have made a selection on dropdowns (<select>), datepickers (<input type="date">) and file uploads (<input type="file">).

This means it will trigger:

  • when the user picks a value from a <select> dropdown menu,
  • select a date from a date picker associated with <input type="date">,
  • select a file in the file picker for <input type="file">.

Finally, there are cases where the ‘change’ event is fired when the element loses focus after its value was altered.

This is typically seen in elements that involve typing rather than selecting, such as <textarea> or certain types of the <input> element like text, search, url, tel, email, or password.

3. Make sure the element exists

It seems obvious, but this has tripped me up a few times in the past.

Make sure to check if the element you’re trying to attach the event to actually exists in the DOM.

For example, in the past I have done something like the below.

document.getElementById('#myElement').addEventHandler("change", myAction)

At first glance it looks ok, but looking it more closely, we can see that:

document.getElementById('#myElement')

will always return null since it does not need the hash (#).

4. Check that you are using addEventListener correctly

Before we check anything else, we should make sure that we are at least using addEventListener correctly.

addEventListener will only accept DOM elements that support events - so plain JavaScript objects will not work.

The syntax will look like this:

addEventListener(type, listener, options)

  • type is a string of a “event type” and case-sensitive. So this means that ‘Click’ (and will not work) is different to ‘click’. You can see all possible event types here: Events
  • listener is a function reference.

A common way to use “addEventListener” is as follows:

    let button = document.querySelector('#smallButton');
    button.addEventListener('click', function() {
        console.log('Button clicked!');
    });

Tip: Check the event handler (listener) parameter

The “listener” parameter is a function reference. In other words, if you are passing a function, make sure you are not executing it. For example this will fail:

.addEventHandler("change", myAction())

This is because we have the brackets () which means we are running the function straight away!

5. Review other events

If the event is not being caught, it may be because the default behavior of the event is preventing it from propagating. You can stop this by calling event.preventDefault() inside your event handler.

6. Fix other Javascript errors on the page

One problem is that there could be other Javascript errors in your app this is stopping this handler from executing.

JavaScript will stop executing code at the point where it encounters an unhandled error.

You would need to check the browser console to see if theres any errors in the logs and fix them up

A few things to check includes includes:

  • Not matching opening and closing brackets
  • Incorrect variable or function names (JavaScript is case-sensitive)
  • Accessing a variable that has not been defined
  • Trying to access properties or methods on null or undefined - could be result of failed CORS or AJAX calls.

Keep in mind that the order of the scripts in your HTML file matters.

Make sure that any dependencies (like libraries or other custom scripts) are loaded before your script.

Also, ensure your DOM elements are loaded before trying to access them by running your code inside a DOMContentLoaded event handler, or by placing your script tags right before the closing tag.

7. addEventListener vs dispatchEvent

Since there are diffent times where the change event will trigger for different <input> types, <select> and <textarea>, we can use the dispatchEvent to force a trigger!

For example, for text inputs, the change will trigger when the user goes out of the textbox. What if we want the change to trigger on the change of the value immediately?

Or we want to dynamically call the change when something is happening in our code?

This is where “dispatchEvent” comes in.

Consider the following code, we want to trigger a “change” when we update our “word_count”

document.getElementById('subject').addEventListener('keypress', function() {
    var string = this.value
    string = string.replace(/\s+/g, " ");
    var words = string.split(/\s+/).length;
    document.getElementById('word_count').value = words;
}, false);

// ❌ This will not work since "change" is not triggered on value change
document.getElementById('word_count').addEventListener('change', function() {
    alert('change fired');
}, false);  

The problem is that even when the “word_count” value changes, the “change” is not triggered.

To fix this we need to use the “dispatchEvent” function.

This just fires off a “change” event to our “word_count” element and force the change handler to react!

document.getElementById('subject').addEventListener('keypress', function() {
    var string = this.value
    string = string.replace(/\s+/g, " ");
    var words = string.split(/\s+/).length;
    document.getElementById('word_count').value = words;

    // ✔️ Force the change to happen
    document.getElementById('word_count').dispatchEvent(new Event('change'));  



}, false);

Summary

In this post, I went through why addEventListener ‘change’ not working in your code. This comes down to the code targeting a invalid HTML element.

The “change” event is only valid for <input>, <select> and <textarea> HMTL elements.

If you know that you are targeting the right HTML elements, then other things to look out for are:

  • Check that the DOM is fully loaded since we do not want to attach to null objects
  • Verify that the element exists and you are targeting it correctly
  • Make sure that you are using addEventListener syntax correctly
  • Review other events - could be something stopping the handler
  • Fix other Javascript errors on the page
  • Consider using dispatchEvent to force the change event to trigger

👋 About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember 😅)

Follow along on Twitter , GitHub and YouTube