Reputation: 85
// Add event listener to second button
document.getElementById('button2').addEventListener('click', () => {
console.log('Button 2 clicked');
});
class ElementSelector {
constructor() {
this.selectorModeEnabled = false;
this.selectedElement = null;
this.selectElement = this.selectElement.bind(this);
this.onSelectElement = (element) => {
console.log('Selected element:', element);
};
}
enableSelectorMode() {
this.selectorModeEnabled = true;
document.body.style.cursor = "crosshair";
document.body.addEventListener("click", this.selectElement);
}
disableSelectorMode() {
this.selectorModeEnabled = false;
document.body.style.cursor = "default";
document.body.removeEventListener("click", this.selectElement);
}
toggleSelectorMode() {
if (this.selectorModeEnabled) {
this.disableSelectorMode();
} else {
this.enableSelectorMode();
}
}
selectElement(event) {
event.preventDefault();
event.stopPropagation();
const element = event.target;
this.selectedElement = element;
this.onSelectElement(element);
}
}
// Initialize and set up toggle button
const selector = new ElementSelector();
document.getElementById('toggleSelector').addEventListener('click', () => {
selector.toggleSelectorMode();
});
<!DOCTYPE html>
<html>
<head>
<title>Element Selector Issue</title>
</head>
<body>
<button onclick="console.log('Button 1 clicked')">Button 1</button>
<button id="button2">Button 2</button>
<button id="toggleSelector">Toggle Selector Mode</button>
</body>
</html>
When I click a button like this while in selection mode:
<button onclick="console.log('Button 1 clicked')">Click</button>
The console.log still fires even though I'm using both event.preventDefault()
and event.stopPropagation()
. I even tried event.stopImmediatePropagation()
but the original click handlers still execute.
How can I completely prevent all click events from firing on elements while in selection mode?
Expected behavior: When in selection mode, clicking an element should only trigger my selection logic, not any existing click handlers.
Actual behavior: Original click handlers (both onclick attributes and addEventListener) still fire even with event.preventDefault() and stopPropagation().
Any help would be appreciated!
Upvotes: 1
Views: 56
Reputation: 388
There are two steps you need to do. If you want to prevent any other click in selection mode.
capture: true
stopImmediatePropagation();
Here is the code which work on my local:
<!DOCTYPE html>
<html>
<head>
<title>Element Selector Issue</title>
</head>
<body>
<div class="selection-area">
<button onclick="console.log('Button 1 clicked')">Button 1</button>
<button id="button2">Button 2</button>
</div>
<button id="toggleSelector">Toggle Selector Mode</button>
<script>
document.getElementById("button2").addEventListener("click", () => {
console.log("Button 2 clicked");
});
class ElementSelector {
constructor() {
this.selectorModeEnabled = false;
this.selectedElement = null;
this.selectionArea = document.querySelector(".selection-area");
this.selectElement = this.selectElement.bind(this);
this.onSelectElement = element => {
console.log("Selected element:", element);
};
}
enableSelectorMode() {
this.selectorModeEnabled = true;
this.selectionArea.style.cursor = "crosshair";
this.selectionArea.addEventListener(
"click",
this.selectElement,
true
);
}
disableSelectorMode() {
this.selectorModeEnabled = false;
this.selectionArea.style.cursor = "default";
console.log("-- Disabling Selection Mode --");
this.selectionArea.removeEventListener(
"click",
this.selectElement,
true
);
}
toggleSelectorMode() {
if (this.selectorModeEnabled) {
this.disableSelectorMode();
} else {
this.enableSelectorMode();
}
}
selectElement(event) {
if (!this.selectorModeEnabled) return;
event.preventDefault();
event.stopImmediatePropagation();
console.log("-- preventing other clicks --");
this.selectedElement = event.target;
this.onSelectElement(event.target);
}
}
const selector = new ElementSelector();
document
.getElementById("toggleSelector")
.addEventListener("click", () => {
selector.toggleSelectorMode();
});
</script>
</body>
</html>
Also define your selection Area or container (what ever you prefer to call it).
Because if you define document.body
as selection area it's not gonna disable your selectionMode
as the button for disabling the selectionMode
is also in selection area and the acutal event is not gonna get fired.
Upvotes: 0
Reputation: 782158
Use the capture: true
option to make the document event listener take priority over the element event listeners.
Note that there's a Catch-22 here: When the element selector is enabled, clicking on the "Toggle Select Mode" button no longer runs the toggle function. You might want to add a specific check for this in the selectElement
method.
// Add event listener to second button
document.getElementById('button2').addEventListener('click', () => {
console.log('Button 2 clicked');
});
class ElementSelector {
constructor() {
this.selectorModeEnabled = false;
this.selectedElement = null;
this.selectElement = this.selectElement.bind(this);
this.onSelectElement = (element) => {
console.log('Selected element:', element);
};
}
enableSelectorMode() {
this.selectorModeEnabled = true;
document.body.style.cursor = "crosshair";
document.body.addEventListener("click", this.selectElement, {capture: true});
}
disableSelectorMode() {
this.selectorModeEnabled = false;
document.body.style.cursor = "default";
document.body.removeEventListener("click", this.selectElement);
}
toggleSelectorMode() {
if (this.selectorModeEnabled) {
this.disableSelectorMode();
} else {
this.enableSelectorMode();
}
}
selectElement(event) {
event.preventDefault();
event.stopPropagation();
const element = event.target;
this.selectedElement = element;
this.onSelectElement(element);
}
}
// Initialize and set up toggle button
const selector = new ElementSelector();
document.getElementById('toggleSelector').addEventListener('click', () => {
selector.toggleSelectorMode();
});
<!DOCTYPE html>
<html>
<head>
<title>Element Selector Issue</title>
</head>
<body>
<button onclick="console.log('Button 1 clicked')">Button 1</button>
<button id="button2">Button 2</button>
<button id="toggleSelector">Toggle Selector Mode</button>
</body>
</html>
Upvotes: 1