问题
Why is my click event fired twice in 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");
});
This is what I get in console:
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:
If I remember correctly, I've seen this behavior on at least some browsers, where clicking the label both triggers a click on the label and on the input.
So if you ignore the events where e.target.tagName is "LABEL", you'll just get the one event. At least, that's what I get in my tests:
- Example with both events | Source
- Example filtering out the e.target.tagName = "LABEL" ones | Source
回答2:
I recommend you use the change event on the input[type="checkbox"] which will only be triggered once. So as a solution to the above problem you might do the following:
$("#toggle").on("change", function(e) {
if ($(this).is(":checked"))
console.log("toggle: Show");
else
console.log("toggle: Hide");
});
https://jsfiddle.net/ssrboq3w/
The vanilla JS version using querySelector which isn't compatible with older versions of IE:
document.querySelector('#toggle').addEventListener('change',function(){
if(this.checked)
console.log('toggle: Show');
else
console.log('toggle: Hide');
});
https://jsfiddle.net/rp6vsyh6/
回答3:
This behavior occurs when the input tag is structured within the label tag:
<label for="toggle"><input id="toggle" type="checkbox" checked>Show</label>
If the input checkbox is placed outside label, with the use of the id and for attributes, the multiple firing of the click event will not occur:
<label for="toggle">Show</label>
<input id="toggle" type="checkbox" checked>
来源:https://stackoverflow.com/questions/19595084/why-is-my-click-event-called-twice-in-jquery