Search code examples
javascripthtmldrop-down-menuaddeventlistener

addEventListener updates global variable with previously selected value


I've been successfully using the following JS to set global variables when drop-down menus are changed, via an addEventListener action.

But when I re-used it today for a new menu, the global variable was not updated until the menu option was changed for the third time. And then, the variable was updated to the value from the previously selected menu option.

It seems the eventlistener was not running until the third time the menu is changed, despite the setTestValue() function being called.

So this is happening:

Menu value selected valueStored times function called
Start value Default 1
9 Default 2
8 Default 3
7 8 4
6 7 5

I'd like advice on why this could be happening and a fix for it. Thanks.

(CodePen link)

<!-- test menu code -->
  <select id="testMenu" onchange="setTestValue()" class="menu shadow">
    <option value="9999" selected>9999</option>
    <option value="9">9</option>
    <option value="8">8</option>
    <option value="7">7</option>
    <option value="6">6</option>
    <option value="5">5</option>
    <option value="4">4</option>
    <option value="3">3</option>
    <option value="2">2</option>
    <option value="1">1</option>
  </select>
// test menu javascript

var selected;
var stored = "Default";

function setTestValue() {
  selected = document.getElementById("testMenu");
  selected.addEventListener("change", function handleChange(event) {
    stored = Number(event.target.value);
  });

  console.log("stored is: " + stored);
  console.log("stored type: " + typeof stored);
}


Solution

  • Rewrite your code like this:

    document.getElementById("testMenu").addEventListener("change", setTestValue);
    
    function setTestValue(event) {
      stored = Number(event.target.value);
      console.log("stored is: " + stored);
      console.log("stored type: " + typeof stored);
    }
    

    And remove the onchange attribute completely from the HTML.

    As pointed out in the comments, you are defining an event listener in a listener for the event, which is why you’re seeing this strange behaviour and not what you expect. No need to addEventListener if you’re using onchange (same thing).