I'm developing a game using Phaser 3 within a Vue.js application that uses Bootstrap 5 for UI components. I've encountered a performance issue: whenever a user clicks to move a piece in the game, a Bootstrap click event is being triggered and processed, causing frame drops.
Using Chrome's performance profiler [screenshot], I can see that:
I've attempted several approaches to prevent Bootstrap from handling events on the game container:
// In mounted() method
this.$refs.gameContainer.addEventListener('click', this.stopEvent, true);
this.$refs.gameContainer.addEventListener('mousedown', this.stopEvent, true);
// Same for mouseup, touchstart, touchend, touchmove
stopEvent: function(event) {
event.stopPropagation();
event.preventDefault();
}
stopEvent: function(event) {
if (this.$refs.gameContainer && this.$refs.gameContainer.contains(event.target)) {
const isBootstrapEvent = new Error().stack.includes('bootstrap');
if (isBootstrapEvent) {
event.stopPropagation();
event.preventDefault();
}
}
}
this.input.on("pointerdown", this.stopEvent, this);
this.input.on("pointerup", this.stopEvent, this);
stopEvent(pointer) {
const event = pointer.event;
event.stopPropagation();
event.preventDefault();
}
<div id="game-container" ref="gameContainer" data-bs-no-jquery="true"/>
.bootstrap-element {
pointer-events: none;
}
#game-container {
pointer-events: auto;
}
Unfortunately, these solutions either:
Is there an official way to tell Bootstrap to ignore events on specific DOM elements or containers?
Is there a way to configure Bootstrap's event delegation system to exclude certain elements from event processing?
Are there any known conflicts between Bootstrap's event handling and canvas-based libraries like Phaser, and any recommended solutions?
Any guidance would be greatly appreciated. Thank you!
I identified two key issues in my previous tests:
stopPropagation()
instead of stopImmediatePropagation()
- the latter prevents all subsequent handlers from executingHere's the working solution (must be placed before Bootstrap import):
document.addEventListener('click', (event) => {
if(event.target.nodeName === 'CANVAS') {
event.stopImmediatePropagation();
}
}, true);
import('bootstrap/dist/js/bootstrap.min.js');
Although effective, this workaround has limitations:
This approach blocks all click events on canvas elements, affecting both Phaser and Google Tag Manager. In my case, this wasn't problematic since I'm using mouseup/mousedown events in Phaser rather than click events.
If you need click event functionality, you can follow @C3roe's suggestion to stop and then manually re-propagate the event to specific handlers.
An official Bootstrap method to exclude specific DOM elements from event handling would be preferable.