Reputation: 549
<label for="foo">Click me to trigger the button</label>
<button id="foo">I'm a button</button>
Say you have a label associated with a button like the above. Clicking on the label triggers a click on the button. Is there any way to detect from within an event handler whether the click came from the label?
document.querySelector("#foo").addEventListener("click", function(event) {
console.log(event.target); //is always button element.
const labelWasClicked = ???;
if (labelWasClicked) {
// do something
} else {
// do something else
}
});
Upvotes: 2
Views: 1147
Reputation: 1158
If you put the label and button in a div and fire the event on that, the event target will be the label when the label is clicked, and the button when the button is clicked, for example:
document.querySelector("#myDiv").addEventListener("click", function(e) {
e.preventDefault();
console.log('target:', e.target);
});
<div id="myDiv">
<label for="foo">Click me to trigger the button</label>
<button id="foo">I'm a button</button>
</div>
Upvotes: 1
Reputation: 1335
Click event has isTrusted
property, which gets false
, if click was triggered from script. I hoped, that label-click will show false as well... but it appeared to be "true". You still can emulate the label behavior and use isTrusted
, if it doesn't matter for other parts of the code.
document.addEventListener("click", function(e) {
let label = e.target.closest(".pseudo-label");
if(!label) return;
if( e.target.closest("#" + label.dataset.for ) ) return;
document.getElementById( label.dataset.for ).click();
});
document.querySelector("#foo").addEventListener("click", function(event) {
console.log(event.isTrusted);
});
.pseudo-label {
border: 1px solid red;
padding: 15px;
user-select: none;
}
<div class="pseudo-label" data-for="foo">Click me to trigger the button <button id="foo">I'm a button</button> </div>
But this seems useless))
You can just separate the code in two different listeners, and use a boolean variable to detect the required click:
let labelClicked = false;
first('label[for="foo"]').addEventListener("click", function() {
labelClicked = true;
console.log("label click");
});
first("#foo").addEventListener("click", function(e) {
console.log("general click"); // You might divide this in two...
if( labelClicked ) return labelClicked = false;
console.log("button click"); //...separate function calls.
});
/***/
function first(selector) { return document.querySelector(selector); }
label {
border: 1px solid red;
padding: 15px;
user-select: none;
}
<label for="foo">Click me to trigger the button</label>
<button id="foo">I'm a button</button>
Upvotes: 1
Reputation: 21648
document.querySelector("[for=foo]").addEventListener("click", function(event) {
console.log(event.target); // Fires only if you click the label
});
document.querySelector("#foo").addEventListener("click", function(event) {
console.log(event.target); // Fires if you click the label or the button
});
<label for="foo">Click me to trigger the button</label>
<button id="foo">I'm a button</button>
Upvotes: 1
Reputation: 988
It is because you are targeting the DOM element with id="foo".
var labelID;
$('label').click(function() {
labelID = $(this).attr('for');
$('#'+labelID).trigger('click');
});
Upvotes: -2