title | nav_order |
---|---|
Events |
4 |
{: .fs-3 }
Bad {: .label .label-red }
connect() {
document.addEventListener(...);
}
{: .border-red }
Good {: .label .label-green }
<div data-controller="gallery" data-action="resize@window->gallery#layout">...</div>
{: .border-green }
layout(e) {
...
}
{: .border-green }
Stimulus will handle the adding and removing of event listeners.
The controller code makes assumption about the markup, which may not be feasible if you're creating a Stimulus controller library. In this case, be sure to unregister your event listeners in disconnect
.
A stimulus controller can connect
/ disconnect
an arbitrary number of times. If eventListeners added in connect
are not cleaned up on disconnect
, you will have more than one eventListener for the given element and thus run your event listener callback multiple times instead of just once.
Bad {: .label .label-red }
connect() {
document.addEventListener("click", this.findFoo.bind(this))
}
disconnect() {
document.removeEventListener("click", this.findFoo.bind(this))
}
findFoo() {
console.log(this.element.querySelector("#foo"))
}
{: .border-red }
Good {: .label .label-green }
connect() {
this.boundFindFoo = this.findFoo.bind(this)
document.addEventListener("click", this.boundFindFoo)
}
disconnect() {
document.removeEventListener("click", this.boundFindFoo)
}
findFoo() {
console.log(this.element.querySelector("#foo"))
}
{: .border-green }
When you call .bind()
on a function, it creates a new function. Therefore, calling bind twice means the
add and remove eventListeners are calling different references of the function and the event wont be removed.
Make sure that when adding and removing event listeners you use the same bound function reference.