我试图找出一个复选框在用户点击后是否被选中。复选框被 Package 在一个标签中,这个标签也必须是可点击的。我的HTML代码是:
<div id="view_container">a</div>
<script type="text/template" id="view_template">
<ul>
<li>
<label>
<input type="checkbox" checked="" value="a">A option
</label>
</li>
<li>
<label>
<input type="checkbox" value="b">B option
</label>
</li>
<li>
<label>
<input type="checkbox" value="c">C option
</label>
</li>
</ul>
</script>
响应JavaScript:
View = Backbone.View.extend({
initialize: function() {
console.log('in the init');
this.render();
},
render: function() {
var template = _.template($("#view_template").html(), {});
this.el.html(template);
},
events: {
'click ul li label': 'clicked',
},
clicked: function(e) {
e.stopPropagation();
console.log('e.target is ' + e.target);
console.log('e.currentTarget is ' + e.currentTarget);
var isChecked = $(e.currentTarget).find('input:first').is(':checked');
var selected = $(e.currentTarget).find('input:first').val().trim();
console.log('isChecked is ' + isChecked);
},
});
var view = new View({
el: $("#view_container")
});
jsfiddle是here。
有几个问题。如果我点击输入,它工作正常,isChecked
的值为真。但是,如果我点击标签,函数clicked
执行两次,console.log
输出为:
e.target is [object HTMLLabelElement]
e.currentTarget is [object HTMLLabelElement]
isChecked is false
e.target is [object HTMLInputElement]
e.currentTarget is [object HTMLLabelElement]
isChecked is true
所以isChecked
第一次是假的。
那么,无论用户是点击标签还是直接点击输入,我如何知道复选框是否被选中?当用户点击标签时,我如何阻止处理程序执行两次?
2条答案
按热度按时间zaqlnxep1#
问题在于,本质上,包含
<input>
的标签或通过for
属性连接到它们的标签会在相关输入上触发单击事件。因此,有2个单击事件:<label>
<input>
上触发点击。因此,如果我们侦听label上的click事件,我们将在本例中捕获这两个事件-因为在
<input>
上触发的click也将冒泡到<label>
,因为它是父级。我们可以通过听复选框本身的点击来解决这个问题,而不是听标签。
您可以使用jQuery
is
方法和:checkbox
和:checked
选择器来执行以下操作,如下所示。Updated fiddle
请注意,最好缓存模板函数,而不是每次调用render时都调用
_template
。0lvr5msh2#
请在这里看到最好的答案Why Does a Label Inside an Input Trigger a Click Event。简而言之,它是标签元素的规范。