最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - On element click Trigger event fire twice for input checkbox - Stack Overflow

programmeradmin1浏览0评论

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=".3.1/jquery.min.js"></script>
<div class="test">
  <input type="checkbox" name="">
</div>

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./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test">
  <input type="checkbox" name="">
</div>

Share Improve this question edited Jan 23, 2020 at 9:45 Barmar 784k57 gold badges548 silver badges659 bronze badges asked Jan 23, 2020 at 9:43 IvanIvan 4331 gold badge6 silver badges21 bronze badges 1
  • The checkbox is inside the DIV, and the event bubbles out. – Barmar Commented Jan 23, 2020 at 9:45
Add a ment  | 

4 Answers 4

Reset to default 5

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./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label class="test">
  <input type="checkbox" name="">
</label>

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./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test">
  <input type="checkbox" name="">
</div>

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./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test">
	<input type="checkbox" name="">
</div>

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/en-US/docs/Web/API/EventTarget/addEventListener

Also see here to understand bubbling vs capturing: https://javascript.info/bubbling-and-capturing

发布评论

评论列表(0)

  1. 暂无评论