Harry Robbins
Harry Robbins

Reputation: 549

can I detect whether a button click came from a label

<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

Answers (4)

dikuw
dikuw

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

OPTIMUS PRIME
OPTIMUS PRIME

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

Adrian Brand
Adrian Brand

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

im_baby
im_baby

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');
});

from CSS Tricks

Upvotes: -2

Related Questions