问题
Consider this fiddle. I have an <input type='checkbox'> linked to its corresponding <label>. On their parent, I have a click binding.
The problem is, clicking on the <label> will trigger the parent's click twice, whereas clicking on the <input> will trigger it only once.
Considering I want to keep the current HTML structure (<label> next to the <input>), is there a way to make the <label> behave like the <input> element? (aka trigger the click only once)
EDIT: If i remove the return true; statement from the click handler's function, it wont trigger twice, but also, it won't select the checkbox. Selecting the checkbox is required. Here is a case where I don't have the action on the parent element. If you click on the <label>, it will check the <input>.
回答1:
I found an answer for you here. The trick is to make the label stop bubbling with a custom binding.
<label for="test" data-bind="stopBubble:parentAction">TestLabel</label>
The stopBubble binding is at the link, and also in the Fiddle.
http://jsfiddle.net/9rkrahm6/2/
回答2:
I don't fully understand why this is, but removing the for attribute from your label will prevent this from happening.
The label still sits where it did previously.
EDIT Try this if the div needs to set the box too: HTML:
<div class="parent" data-bind="click: checkTheBox">
<input type="checkbox" id="test" data-bind="checked: checkedFlag">
<label for="test">TestLabel</label>
</div>
JS:
function testVM(){
var self = this;
self.checkedFlag = ko.observable(false);
self.checkTheBox = function(){
console.log("In funct")
console.log("before: " + self.checkedFlag())
if (self.checkedFlag()){
self.checkedFlag(false);
}
else{
self.checkedFlag(true);
}
console.log("after: " + self.checkedFlag())
};
self.myTest = function(data, event){
};
}
ko.applyBindings(new testVM());
回答3:
You can use
event.preventDefault(); // stop bubbling
or simply
return false; // is equals to: event.stopPropagation(); event.preventDefault();
in the parentAction function.
Update
It looks like click event fires down from the checked knockout binding.
The following code will fix it, but it smells like a hack. May be somebody will propose the better treatment.
function testVM(){
var self = this;
self.checkedFlag = ko.observable(false);
self.checkedFlag.subscribe(function() {
event.stopPropagation();
});
self.parentAction = function(data, event){
alert('triggered');
//event.stopPropagation();
//event.preventDefault();
return true;
};
}
来源:https://stackoverflow.com/questions/30629217/clicking-on-an-inputcheckboxs-label-will-fire-twice-the-parents-click-event