-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Prerequisites
- I have searched for duplicate or closed issues
- I have validated any HTML to avoid common problems
- I have read the contributing guidelines
Describe the issue
Marqueefy registers a global window.resize event listener but never removes it during dispose(). While this works for multi page applications, because on page load the event is cleared. But when used in any SPA or with anything like Stimulus/Turbo the event stays bound even after calling dispose();
And this resize listener continues to fire and calls refresh(), leading to runtime errors.
This results in errors like:
Uncaught TypeError: Cannot destructure property 'direction' of 'this._config' as it is nullReduced test cases
Steps to Reproduce
-
Create a Marqueefy instance
-
Call dispose() on the instance
-
Resize the browser window
Expected Behavior
-
dispose() should fully clean up the instance
-
Any global event listeners registered by the instance should be removed
-
No errors should occur after disposal
Actual Behavior
-
The resize event listener remains active
-
On resize, it calls this.refresh()
-
Since dispose() nulls internal properties, refresh() throws error
The root cause is in the _setListeners() method, where an anonymous arrow function is used to bind the listener:
window.addEventListener("resize", () => this.refresh(), {
passive: true
});No reference to the function is stored and thus it's not removed in dispose either. Ideally we should do something like this
this._resizeHandler = () => this.refresh();
window.addEventListener("resize", this._resizeHandler, { passive: true });And then override the dispose method
dispose() {
window.removeEventListener("resize", this._resizeHandler);
this._resizeHandler = null;
super.dispose();
}What operating system(s) are you seeing the problem on?
Windows
What browser(s) are you seeing the problem on?
Chrome
What version of Marqueefy are you using?
1.0.3