Something I've learned about Event Listeners

So it all started when I wanted to use the Character Creation code from https://github.com/ThePix/QuestJS/wiki/Character-Creation (specifically from the Further Customisation section) to create my character and have events listening out for button clicks on the dialog form.

function changePlayerInfo() {
    const diag = document.querySelector("#dialog")
// Do some HTML stuff
    document.querySelector("#dialog-button").addEventListener('click', settings.setUpDialogClick)

If I attempted to reuse the dialog form again with a new popup window I kept getting weird errors about the function settings.setUpDialogClick even though I had registered a completely different function with my form's dialog window, that's because the original Event Listener registered on the settings dialog was actually not gone! So that led me down into a research rabbit hole about how to remove an Event Listener and how Event Listeners work in general.

There are 2 methods for removing an Event Listener, the first and probably easiest is to set the 'once' property as you add it:

document.querySelector("#dialog-button").addEventListener('click', settings.setUpDialogClick, { once: true })

This means it is self destructive after it is called, intended as a one time only use action which is suitable for this Character Creation process.

Now obviously if you intend to reuse a popup form you can still do it with this method if the button's purpose is to close the window but it is not such a good idea if it's meant to be used for multiple uses to capture input from the user while the form is still active, that leads to the second method of removal, something that should be done once the form is being closed at the very least.

document.querySelector("#dialog-button").removeEventListener('click', settings.setUpDialogClick)

The removeEventListener will only work as long as the type 'click' and the listener object 'settings.setUpDialogClick' are exactly the same as when you registered it, so it does get a little trickier to successfully remove it if you don't get these things correct.

One method I've tried was to use the line above directly inside of the code of the function in settings.setUpDialogClick but it wasn't useful for passing in any parameters that the function you use might have beyond the diag, for that we need a callback.

function dialogOkClick(diag, var1, var2) {
    // Return to main game
}

function popupDialog() {
const diag = document.querySelector("#dialog")
var newVar1
var newVar2

// Using callback () => { function(var1, var2) } I can pass in variables from this function popupDialog into the callback function dialogOkClick
document.querySelector("#dialog-button").addEventListener('click', () => { dialogOkClick(diag, newVar1, newVar2) }, { once: true})
}

Now I can both delete my event listener after I am done with it and also customize what input variables I can pass in to the registered event function.

If you won't use once, then we need to keep a reference to the anonymous listener to be able to remove it later manually.

let lastListener;

function popupDialog(oMainObj) {
  lastListener = () => myFunction(diag, oMainObj);
  document.querySelector("#dialog-button").addEventListener('click', lastListener);
}

function myFunction(diag, oMainObj) {
   bla()
}

function bla() {
  // Remove the listener wherever you want
  document.querySelector("#dialog-button").removeEventListener('click', lastListener);
}

I hope that this is useful to someone else as they might come across the same issue I did and not know how to resolve it, and if someone can update the linked page above so it at least uses the { once: true} method that might avoid further confusion for new programmers following the guide that like to use it as a template for further experimentation like I did.


This topic is now closed. Topics are closed after 14 days of inactivity.

Support

Forums