EventTarget. removeEventListener()
Detaches an event handler function added earlier with addEventListener(). Requires the same function and the same event type.
- Returns
undefined
Example
#const like = document.querySelector('#like')
const lock = document.querySelector('#lock')
let likes = 0
function addLike() {
likes += 1
console.log('Likes:', likes)
}
like.addEventListener('click', addLike)
lock.addEventListener('click', () => {
like.removeEventListener('click', addLike)
console.log('Likes blocked')
})
like.click()
lock.click()
like.click()The last like.click() prints nothing, since the addLike function is already detached. Clicking the “Like the lesson” button in the preview won’t change anything either.
Definition and usage
#The removeEventListener() method removes an event handler registered earlier with addEventListener(). After calling it, the function stops reacting to that event: a button stops counting clicks, and a document stops listening for keyboard shortcuts.
The browser identifies the handler to remove by three things: the event type, the function, and the phase, i.e. the capture option. You must pass the exact same function (the same reference), not a different function with identical code. So store a handler you plan to detach someday in a variable or a named function. An anonymous function written directly inside addEventListener() can’t be removed.
If the handler was added with capture: true, pass capture: true when removing it too. Other options, such as once or passive, don’t matter here. Trying to remove a handler that isn’t there doesn’t cause an error, it simply does nothing. A convenient alternative is the signal option in addEventListener(): a single controller.abort() call then detaches every handler registered with that signal.
Syntax
#target.removeEventListener(type, listener)
target.removeEventListener(type, listener, options)
target.removeEventListener(type, listener, useCapture)Parameters
#type
string
The event type, e.g."click". Must be the same as when the handler was added.listener
function
The same function (the same reference) that was passed toaddEventListener().options
optional object or boolean
Onlycapturematters. If the handler was added withcapture: true, pass the same value here.
More examples
#const save = document.querySelector('#save')
save.addEventListener('click', () => console.log('Saved'))
save.removeEventListener('click', () => console.log('Saved'))
save.click()Both arrow functions have the same code, but they’re two different objects. removeEventListener() doesn’t find a matching handler, so it removes nothing.
const menu = document.querySelector('#menu')
const log = (event) => console.log('Clicked:', event.target.textContent)
menu.addEventListener('click', log, { capture: true })
menu.removeEventListener('click', log)
menu.children[0].click()
menu.removeEventListener('click', log, { capture: true })
menu.children[1].click()The first call looks for a handler added without capture, so the function stays. Only passing capture: true detaches it, and clicking “Ranking” no longer prints anything.
const nick = document.querySelector('#nick')
const controller = new AbortController()
const { signal } = controller
nick.addEventListener('input', () => console.log('input:', nick.value), { signal })
nick.addEventListener('change', () => console.log('change:', nick.value), { signal })
nick.value = 'Emma'
nick.dispatchEvent(new Event('input'))
nick.dispatchEvent(new Event('change'))
controller.abort()
nick.value = 'Jack'
nick.dispatchEvent(new Event('input'))
nick.dispatchEvent(new Event('change'))
console.log('Both handlers detached')One controller.abort() call removes every handler added with that same signal at once. No need to remember each function individually.
Browser support
#Widely available
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- Store the handler you plan to remove in a variable or a named function. Passing a “matching” arrow function won’t do anything.
- Watch out for
bind(): every call tothis.onClick.bind(this)creates a new function. Store the result once, e.g. in an object field, and use it for both adding and removing. - When detaching several handlers at once, for example when closing a dialog, it’s simpler to use the
signaloption and a singlecontroller.abort()call.
Related entries
#- EventTarget.addEventListener()Registers a function that’s called every time a given event occurs on an element, for example a click.
- AbortControllerLets you cancel an asynchronous operation, e.g. a fetch() request, and detach many event handlers at once with a single abort() call.
- EventTarget.dispatchEvent()Fires an event on an element from code. Together with CustomEvent, it lets you create custom events carrying extra data.
- Event.targetThe element on which an event actually occurred, for example the clicked button inside a list.
- () => {}An arrow function: a shorter function syntax, with no own this, and an implicit return for a single expression.
Spotted a mistake or missing an example? Write to us.