我试图找出一个复选框ID是否在用户点击之后没有被扯掉。 checkox包裹在一个必须可点击的标签中。我的代码是:
<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
的值为true。但是,如果我单击标签,则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
第一次是假的。
那么,无论是否用户点击标签或直接在输入上,我如何知道是否正在检查复选框?当用户点击标签时,如何阻止处理程序执行两次?
答案 0 :(得分:9)
问题在于,本质上,包含<input>
s或通过for
属性连接到它们的标签会触发相关输入的点击事件。所以有2个点击事件:
<label>
<input>
上的标签触发。因此,如果我们在标签上收听点击事件,我们会在这种情况下抓住这两个事件 - 因为<input>
上触发的点击也会冒出<label>
,因为它是父母
我们可以通过点击复选框本身而不是标签来解决这个问题。
您可以使用带有:checkbox
和:checked
选择器的jQuery is
方法执行以下操作,如下所示。
View = Backbone.View.extend({
initialize: function () {
this.render();
},
template: _.template($("#view_template").html()),
events: {
'click ul li :checkbox': 'clicked',
},
render: function () {
this.$el.append(this.template({}));
},
clicked: function (e) {
var $target = $(e.target);
var selected = $target .is(':checked');
console.log('selected: ', selected, 'value: ', $target.val());
}
});
var view = new View({
el: $("#view_container")
});
请注意,缓存模板函数是一种很好的做法,而不是每次调用渲染时调用_template
。
答案 1 :(得分:0)
请在此处查看最佳答案 Why Does a Label Inside an Input Trigger a Click Event。 简而言之,它是标签元素的规范。