为什么在这个html / css / jquery中注册了两个点击事件
我正在设计一个复选框列表。 我已经添加了我的样式,并且它们在呈现时正确显示。 我想在复选框的标签被点击时添加一个类。 这是我的标记,在jsfiddle中也是这样。 您可以从我的小提琴中看到,只需点击一次即可注册两个点击事件。 为什么?
HTML:
<ul>
<li>
<label for="test_0" class="">
<input id="test_0" name="offering_cycle" type="checkbox" value="1"> Fall
</label>
</li>
<li>
<label for="test_1" class="">
<input id="test_1" name="offering_cycle" type="checkbox" value="2"> Spring
</label>
</li>
<li>
<label for="test_2" class="">
<input id="test_2" name="offering_cycle" type="checkbox" value="3"> Summer
</label>
</li>
<li>
<label for="test_3" class="">
<input id="test_3" name="offering_cycle" type="checkbox" value="4"> Other
</label>
</li>
</ul>
CSS:
ul {
list-style-type:none;
}
label {
position:relative;
display:inline-block;
padding-left:27px;
height:25px;
}
label:before {
display:block;
position:absolute;
top:-2px;
margin-left:-28px;
width:18px;
height:18px;
background-color:#fff;
border-radius:5px;
border:1px solid #ccc;
text-align: center;
color:#fff;
font-size:18px;
content:'a';
}
input {
width:1px;
height:1px;
border:0;
opacity:0;
float:right;
}
jQuery的:
$('label[for*=test_]').on('click',function(){
$(this).toggleClass('testing');
});
原因标签的点击处理程序被调用两次:
单击与输入相关联的标签会导致触发两个点击事件。 触发标签的第一个点击事件。 该点击事件的默认处理会导致触发相关输入的第二个点击事件。 由于您将输入作为标签的后代,因此第二个点击事件会起泡至标签。 这就是为什么你的点击事件处理程序被调用两次。
如果您确实想要处理标签的点击事件(并且只需点击一下就执行一次):
(1)如果您愿意且能够修改HTML,则可以移动输入,使其不是标签的后代。 仍然会有两个点击事件,但第二个点击事件不会从输入到标签的起泡,因为标签不再是输入的祖先。
当输入不是标签的后代时,您必须使用标签的“for”属性将其与输入关联。 “for”属性的值应该是输入的“id”值。 (您已经包含适当值的“for”属性。)
<input id="test_0" name="offering_cycle" type="checkbox" value="1">
<label for="test_0" class="">Fall</label>
(2)防止第一次点击事件的默认处理可以防止第二次点击事件被触发, 但这样做会破坏标签 。 也就是说,当点击标签时,复选框不会被选中/取消选中。
$('label[for*=test_]').on('click', function(event) {
event.preventDefault();
$(this).toggleClass('testing');
// returning false would be another way to prevent the default handling.
});
的jsfiddle
(3)相反,您可以停止从输入冒泡的第二个点击事件。
$('input:checkbox').on('click', function(event) {
event.stopPropagation();
});
$('label[for*=test_]').on('click', function() {
$(this).toggleClass('testing');
});
的jsfiddle
注意:如果输入不是标签的子项,则不需要。
(4)或者你可以检查处理程序中的事件目标。 它将成为第一次点击事件的标签和第二次点击事件的输入。 以下处理程序仅在第一次单击事件中执行if语句内的代码。
$('label[for*=test_]').on('click', function(event) {
if (event.target == this) {
$(this).toggleClass('testing');
}
});
的jsfiddle
注意:如果输入不是标签的子元素,上面的代码仍然可以工作,但if语句是不必要的,因为触发输入的点击事件不会冒泡到标签。
改为处理输入的点击:
就你而言,你并不需要为标签元素注册点击处理程序。 您可以为输入注册一个单击(或更改)处理程序。 然后,您可以使用$(this).closest('label')
来获取标签元素。
$('input[name=offering_cycle]').on('click', function() {
$(this).closest('label').toggleClass('testing');
});
的jsfiddle
注意:如果输入不是标签的孩子,上面的处理程序仍然会在您点击标签时被调用,但是$(this).closest('label')
不会获得标签。 您将不得不使用类似$('label[for="' + this.id + '"]')
。
关于标签元素上的“for”属性:
由于标签内有输入,因此不需要在标签中包含for
属性---但它不是无效的。
您已将“for”属性值设置为输入元素的“id”属性的值。 这是使用“for”属性将标签与输入相关联的正确方法。 如果要包含具有无效值的“for”属性,即使输入是标签的后代,标签也不会与输入关联。
从标签元素的“for”属性的HTML5规范中:
可以指定for属性来指示要与标题相关联的表单控件。 如果指定了该属性,则该属性的值必须是与该标签元素相同的文档中的可标识元素的标识。 如果指定了属性并且Document中的元素的ID等于for属性的值,并且第一个这样的元素是可标记的元素,那么该元素是标签元素的标签控件。
如果未指定for属性,但标签元素具有可标记的元素后代,则第一个树形顺序的后代是标签元素的标签控件。
你也可以尝试:
$('label[for^="test_"]').click(function(){
$('div#target').append($(this).clone());
return false;
});
这是因为你在包含checkbox
label
上绑定事件,而你正在使用for="chekbox_id"
。 所以,这个事件被激发用于label
以及checkbox
。
<ul>
<li>
<label for="test_0" class="">Fall</label>
<input id="test_0" name="offering_cycle" type="checkbox" value="1" />
</li>
<li>
<label for="test_1" class="">Spring</label>
<input id="test_1" name="offering_cycle" type="checkbox" value="2" />
</li>
<li>
<label for="test_2" class="">Summer</label>
<input id="test_2" name="offering_cycle" type="checkbox" value="3" />
</li>
<li>
<label for="test_3" class="">Other</label>
<input id="test_3" name="offering_cycle" type="checkbox" value="4" />
</li>
</ul>
<div id="target"></div>
从label
取出input
。
演示:http://jsfiddle.net/tusharj/fdm1pmj2/5/
链接地址: http://www.djcxy.com/p/85677.html上一篇: Why are two click events registered in this html/css/jquery
下一篇: Result type does not implement method in scope named `unwrap`