Search code examples
javascriptcustom-events

Adding javascript custom events dynamically and having them triggered correctly


I am trying to use custom JavaScript events dynamically, but they are seemingly queued in a way I don't wish. Example code:

<html>
  <body>
    <div id="app">
      Testing
    </div>
<script>
  console.log("Sending event");
  const event = new Event('testEvent', { cancelable: true });
  document.body.querySelector('#app').dispatchEvent(event);
  console.log("Event sent");

  // now add an event handler
  console.log("Adding listener");
  document.body.querySelector('#app').addEventListener("testEvent", eventHandler());

  // now send the event again
  console.log("Sending event again");
  document.body.querySelector('#app').dispatchEvent(event);
  console.log("Event sent, done");

  function eventHandler(evt) {
    console.log("In eventHandler, got event");
  };
</script>
  </body>
</html>

Here I am triggering a custom event, then adding an event handler, then triggering the custom event again. What happens, in Chrome at least, is that the event handler is called by the first trigger, even though the trigger happened before I added the event handler. Also, the event handler is not called a second time, even after I trigger the event again.

I don't want the first trigger to cause the event handler to be called. And I do want the second trigger to cause it to be called. What am I doing wrong?


Solution

  • You are invoking the event handler function and passing the return value to addEventListener, which is why it runs instantly and only once. Instead, you should pass the function.

    document.body.querySelector('#app').addEventListener("testEvent", eventHandler);
    //not document.body.querySelector('#app').addEventListener("testEvent", eventHandler());
    

    <html>
      <body>
        <div id="app">
          Testing
        </div>
    <script>
      console.log("Sending event");
      const event = new Event('testEvent', { cancelable: true });
      document.body.querySelector('#app').dispatchEvent(event);
      console.log("Event sent");
    
      // now add an event handler
      console.log("Adding listener");
      document.body.querySelector('#app').addEventListener("testEvent", eventHandler);
    
      // now send the event again
      console.log("Sending event again");
      document.body.querySelector('#app').dispatchEvent(event);
      console.log("Event sent, done");
    
      function eventHandler(evt) {
        console.log("In eventHandler, got event");
      };
    </script>
      </body>
    </html>