Yes, the listener still exists. In Chrome and FF devtools, there is a function called getEventListener(node)
. Experiment with it, and notice that even after your call el.remove()
, there are still event listeners attached to that element.

This means that if we remove an element and add the same element to anywhere in our HTML, the event listener still works:
const c = document.getElementById("c")
c.addEventListener("click", () => alert("clicked"))
setTimeout(() => c.remove(), 1000)
setTimeout(() => document.body.appendChild(c), 2000)
<button id="c">click</button>
But is this necessarily a problem? No, not really. The browser optimizes your code and, as mentioned in this post, that isn't something that should bother you. Your concern for overloading events, as well, should not be an issue; browsers have been optimized for decades; your events are stored in a list of listeners for a specific event that is only looked up when the user fires the event.
The only way I envision a problem is if you leave everything dangling and don't clean it up with scope. Take this example:
const length = 1_000_000
const elements = Array.from({ length }, () => {
const el = document.createElement("button")
el.addEventListener("click", () => alert("do something..."))
})
elements.forEach(el => el.remove()) // <-- this does NOT free up our listener functions, however
As mentioned, we can use scope to automatically discard our values or explicitly call el.removeEventListener
(but you'll need a reference to that function).