Почему событие jquery дважды вызывает jquery?

Почему мое событие click дважды запускается в jquery?

HTML

<ul class=submenu>
    <li><label for=toggle><input id=toggle type=checkbox checked>Show</label></li>
</ul>

Javascript

$("ul.submenu li:contains('Show')").on("click", function(e) {
    console.log("toggle");
    if ($(this).find("[type=checkbox]").is(":checked")) console.log("Show");
    else console.log("Hide");
});

Это то, что я получаю в консоли:

toggle                     menu.js:39
Show                       menu.js:40
toggle                     menu.js:39
Hide                       menu.js:41


> $("ul.submenu li:contains('Show')")
[<li>​                                            ]
    <label for=​"toggle">​
      <input id=​"toggle" type=​"checkbox" checked>​
      "Show"
    </label>​
</li>​

Ответ 1

Если я правильно помню, я видел это поведение, по крайней мере, в некоторых браузерах, нажав label, оба триггера нажимают на label и на input.

Итак, если вы проигнорируете события, где e.target.tagName "LABEL", вы просто получите одно событие. По крайней мере, это то, что я получаю в своих тестах:

Ответ 2

Это происходит, когда тег input структурирован в теге label:

<label for="toggle"><input id="toggle" type="checkbox" checked>Show</label>

Если флажок input размещен вне label, с использованием атрибутов id и for, многократное срабатывание события click не произойдет:

<label for="toggle">Show</label>
<input id="toggle" type="checkbox" checked>

Ответ 3

Я рекомендую вам использовать событие change в input[type="checkbox"], которое будет запускаться только один раз. Итак, как решение вышеуказанной проблемы вы можете сделать следующее:

$("#toggle").on("change", function(e) {
  if ($(this).is(":checked"))
    console.log("toggle: Show");
  else
    console.log("toggle: Hide");
});

https://jsfiddle.net/ssrboq3w/

Версия Vanilla JS с использованием querySelector, которая несовместима со старыми версиями IE:

document.querySelector('#toggle').addEventListener('change',function(){
  if(this.checked)
    console.log('toggle: Show');
  else
    console.log('toggle: Hide');
});

https://jsfiddle.net/rp6vsyh6/