diff --git a/src/engine/input/pointer-event-receiver.ts b/src/engine/input/pointer-event-receiver.ts index 5a217e50..da84af3e 100644 --- a/src/engine/input/pointer-event-receiver.ts +++ b/src/engine/input/pointer-event-receiver.ts @@ -384,10 +384,10 @@ export class PointerEventReceiver { this.target.removeEventListener('wheel', this._boundWheel); } else if (document.onmousewheel !== undefined) { // Webkit and IE - this.target.addEventListener('mousewheel', this._boundWheel); + this.target.removeEventListener('mousewheel', this._boundWheel); } else { // Remaining browser and older Firefox - this.target.addEventListener('MozMousePixelScroll', this._boundWheel); + this.target.removeEventListener('MozMousePixelScroll', this._boundWheel); } } diff --git a/src/spec/vitest/pointer-input-spec.ts b/src/spec/vitest/pointer-input-spec.ts index cfabb4be..94a1bb54 100644 --- a/src/spec/vitest/pointer-input-spec.ts +++ b/src/spec/vitest/pointer-input-spec.ts @@ -427,4 +427,23 @@ describe('A pointer', () => { expect(wheelHandler).toHaveBeenCalledTimes(1); }); }); + + describe('detach', () => { + it('should properly remove wheel event listeners on detach', () => { + const receiver = engine.input.pointers as any; + const target = receiver.target; + + const removeEventListenerSpy = vi.spyOn(target, 'removeEventListener'); + + receiver.detach(); + + // Should call removeEventListener, not addEventListener, for wheel events + const wheelCalls = removeEventListenerSpy.mock.calls.filter( + (call) => call[0] === 'wheel' || call[0] === 'mousewheel' || call[0] === 'MozMousePixelScroll' + ); + expect(wheelCalls.length).toBeGreaterThan(0); + + removeEventListenerSpy.mockRestore(); + }); + }); });