Reputation: 433
when i click on the div element should trigger click on checkbox only once but for some reason i get event fired twice , i saw other topics with similar problem but noone helped me
$('div').click(function(e) {
$('input').trigger('click');
check();
});
function check() {
if ($('input').is(':checked')) {
console.log('input cheked')
} else {
console.log('unchecked')
}
}
.test {
height: 150px;
width: 150px;
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test">
<input type="checkbox" name="">
</div>
Upvotes: 2
Views: 3123
Reputation: 298
JQuery uses event bubbling when setting up events. This means that when you click the input the event is fired once for the input and then it 'bubbles' up the DOM tree to the parent DIV. This then notices the click event on the DIV and fires again. Therefore the event fires twice, once for the input and again for the DIV.
To stop this you will need to use the 'capture' technique instead of event bubbling. This would mean that you would use addEventListener
and pass in the option as the third argument as true.
See here: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
Also see here to understand bubbling vs capturing: https://javascript.info/bubbling-and-capturing
Upvotes: 0
Reputation: 1751
Your checkbox is inside div and you are binding click evet to div and from that you are triggering checkbox click event which again triggers click of div. That's why it's triggering 2 times.
You can directly go for checkbox change event:
$(':checkbox').on('change', function() {
if (this.checked) {
console.log('input checked')
} else {
console.log('unchecked')
}
});
.test{
height: 150px;
width: 150px;
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test">
<input type="checkbox" name="">
</div>
Upvotes: 0
Reputation: 911
That is because, when you are trigerring click on the input the event is being bubbles to all its parents. To stop that use e.stopPropagation
on the click event handler of input.
$('input').click(function(e) {
e.stopPropagation();
});
Read more about bubbling and capturing here.
Check the working code below:
$('div').click(function(e) {
$('input').trigger('click');
check();
});
$('input').click(function(e) {
e.stopPropagation();
});
function check() {
if ($('input').is(':checked')) {
console.log('input cheked')
} else {
console.log('unchecked')
}
}
.test {
height: 150px;
width: 150px;
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test">
<input type="checkbox" name="">
</div>
Upvotes: 1
Reputation: 337580
The issue is because the click occurs on the div
, which triggers a click
on the child checkbox which in turn propagates up the DOM and runs the click handler on the div
again.
If you are trying to create a bigger hit-area for the checkbox, just use a label
element instead. Then you get this behaviour for free without needing any JS.
If you want to know the state of a checkbox when it's changed, hook a change
event handler to it. Try this:
$(':checkbox').on('change', function() {
if (this.checked) {
console.log('input checked')
} else {
console.log('unchecked')
}
});
.test {
height: 150px;
width: 150px;
background: red;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label class="test">
<input type="checkbox" name="">
</label>
Upvotes: 5