0

Using Javascript, how do you remove a single function from a "click" event listener, after the first click event, when there are multiple functions being used on the element with the "click" event listener? Here, after the first click, only toggleView() should remain and renderList() should be removed.

const button = document.getElementById("view_button");
button.addEventListener("click", () => {
  toggleView(); // want to keep this indefinitely
  renderList(); // want to remove this after the first click
  button.removeEventListener("click", renderList);
});
2
  • Is adding 2 event listeners a choice or you need to handle both functions in the same listener? Adding 2 separate listeners would be a choice because you could remove the one calling renderList after executing once Commented Oct 27, 2021 at 17:55
  • From the code you posted, there's only one event handler, that anonymous arrow function. To get what you want, set a flag to keep track of whether a "click" has been handled, and use that to run or not run the second function. Commented Oct 27, 2021 at 17:55

3 Answers 3

1

You need to add both separately, and specify { once: true } on the one you want removed after first execution.

See MDN:

once
A boolean value indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.

function toggleView() {
  console.log('toggleView');
}

function renderList(evt) {
  console.log('renderList');
}


const button = document.getElementById("view_button");
button.addEventListener("click", toggleView);
button.addEventListener("click", renderList, { once: true });
<button type="button" id="view_button">Click</button>

Sign up to request clarification or add additional context in comments.

2 Comments

For my own knowledge, what order are they executed in? The order in which the listeners are added?
Depending on whether you also have any delegate listeners, and also if you configred your listeners using { capture: true } (which reverses bubbling into trickling). In general, first all listeners that are registered directly on the event emitter are called, in order of registration. Then those attached on the parent, also always in order of registration. This continues until you eventually reach document or window.
0

You can add two event listeners and remove the one

function toggleView() {
  console.log('toggleView');
}

function renderList(evt) {
  evt.currentTarget.removeEventListener("click", renderList);
  console.log('renderList');
}


const button = document.getElementById("view_button");
button.addEventListener("click", toggleView);
button.addEventListener("click", renderList);
<button type="button" id="view_button">Click</button>

or you can just add logic to determine if the function should be run.

function toggleView() {
  console.log('toggleView');
}

function renderList() {
  console.log('renderList');
}


const button = document.getElementById("view_button");
button.addEventListener("click", () => {
  toggleView();
  if (!button.dataset.clicked) {
    renderList();
    button.dataset.clicked = '1';
  }
});
<button type="button" id="view_button">Click</button>

1 Comment

No need for manual removal here, check once optional parameter: developer.mozilla.org/en-US/docs/Web/API/EventTarget/…
0

I would use a closure here to keep track of if the item has been clicked.

const button = document.getElementById("view_button");

function toggleView() {
  console.log('Toggle View');
}

function renderList() {
  console.log('Render List');
}

function clickHandler() {
  let hasBeenClicked = false;
  return function () { 
      toggleView();
      if (!hasBeenClicked) {
        renderList();
        hasBeenClicked = true;
     }
  };  
}



button.addEventListener("click", clickHandler());
<button id="view_button" type="button">View Button</button>

1 Comment

Again, for what OP needs the EventTarget API specifically already offers a solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.