Reputation: 208
NO jQuery
I am currently checking if the user pressed outside an element. However, when console.log
ging the event.target
, I see that one click happen on 2 elements (one is an input element and the other one is a label). The label element is showing first, which results in the function thinking that the press did not happen on the input element and therefore the click occurred outside of the element but that's not true.
The reason I want to check if the press was outside the input element and not the label, is because there are <span>
's and other elements that get triggered when clicking.
My code so far:
document.addEventListener("click", function(event) {checkChecked(event); });
function checkChecked(inputEvent) {
if(inputElement !== inputEvent.target && !inputElement.contains(inputEvent.target)) {
console.log("click outside");
}
}
And the HTML:
<li class="payment-shipping-method checked">
<h3>
<input type="radio" name="paymentMethodId" id="payment-method-7-radio" class="payment-method" value="7" checked="">
<label for="payment-method-7-radio">
<span class="figure"><b><img src="img" alt=""></b></span>
<span class="caption">caption<span class="price zero">
<span class="amount">0</span>
<span class="currency"> kr</span>
</span><i>caption</i></span>
</label>
</h3>
<div class="description"></div>
</li>
How can I do this?
Upvotes: 1
Views: 348
Reputation: 12113
I looked into this a bit more, and found this was not as easy as I thought, but still possible. Of note in this edit:
addEventListener
line a bit. Since checkChecked
takes a single event
argument like all event handlers, we can just reference it directly.inputEvent.target.closest("label")
to get the closest label
ancestor of the clicked element, but for some reason that wasn't working in the snippet. I included a quick recreation of the functionality in the getClosest
function.document.addEventListener("click", checkChecked);
var inputElement = document.getElementById("payment-method-7-radio");
// For some reason, while I was building this snippet,
// I found the native Element.closest function was not
// working, and built this substitute
function getClosest(fromElement, toSelector) {
if (fromElement.matches(toSelector)) {
return fromElement;
}
if (fromElement === document.documentElement) {
return null;
}
return getClosest(fromElement.parentElement, toSelector);
}
function checkChecked(inputEvent) {
var closestLabel = getClosest(inputEvent.target, "label");
if (inputElement !== inputEvent.target &&
(!closestLabel || closestLabel.getAttribute("for") !== inputElement.id)) {
console.log("click outside");
return;
}
if (inputElement === inputEvent.target) {
console.log("clicked element");
}
if (closestLabel && closestLabel.getAttribute("for") === inputElement.id) {
console.log("clicked label");
}
}
<li class="payment-shipping-method checked">
<h3>
<input type="radio" name="paymentMethodId" id="payment-method-7-radio" class="payment-method" value="7" checked="">
<label for="payment-method-7-radio">
<span class="figure"><b><img src="img" alt=""></b></span>
<span class="caption">caption<span class="price zero">
<span class="amount">0</span>
<span class="currency"> kr</span>
</span><i>caption</i></span>
</label>
</h3>
<div class="description"></div>
</li>
Upvotes: 1
Reputation: 697
you are adding a listener to the document, so the callback will be called on any click
replace the first line with this and don't forget to modify the selector
document.querySelector('yourInputsSelector').addEventListener('click', checkChecked)
Upvotes: 0