Javascript 为什么在这个html/css/jquery中注册了两个单击事件
我正在尝试设置复选框列表的样式。我已经添加了我的样式,它们在渲染时显示正确。我想在单击复选框的标签时添加一个类。这是我的标记和标记。您可以从我的小提琴中看到,只需单击一次即可注册两次单击事件。为什么? html: jquery:Javascript 为什么在这个html/css/jquery中注册了两个单击事件,javascript,jquery,html,css,javascript-events,Javascript,Jquery,Html,Css,Javascript Events,我正在尝试设置复选框列表的样式。我已经添加了我的样式,它们在渲染时显示正确。我想在单击复选框的标签时添加一个类。这是我的标记和标记。您可以从我的小提琴中看到,只需单击一次即可注册两次单击事件。为什么? html: jquery: $('label[for*=test_]').on('click',function(){ $(this).toggleClass('testing'); }); 您也可以尝试: $('label[for^="test_"]').click(function(
$('label[for*=test_]').on('click',function(){
$(this).toggleClass('testing');
});
您也可以尝试:
$('label[for^="test_"]').click(function(){
$('div#target').append($(this).clone());
return false;
});
给定标签上的for属性应链接到输入的名称,而不是id
您可以对事件调用方法stopPropagation
,然后将事件注入到click处理程序中
例如:
$('label[for*=test_]').on('click',function(e){
e.stopPropagation();
});
html示例:
<div class="parent something">
<div class="child something">
</div>
</div>
现在,如果您在div.something
上有一个单击处理程序,它不会触发两次,但您仍然可以同时使用这两个处理程序
资料来源:
<ul>
<li>
<label for="test_0" class="testClass">
<input id="test_0" name="offering_cycle" type="checkbox" value="1"> Fall
</label>
</li>
<li>
<label for="test_1" class="testClass">
<input id="test_1" name="offering_cycle" type="checkbox" value="2"> Spring
</label>
</li>
<li>
<label for="test_2" class="testClass">
<input id="test_2" name="offering_cycle" type="checkbox" value="3"> Summer
</label>
</li>
<li>
<label for="test_3" class="testClass">
<input id="test_3" name="offering_cycle" type="checkbox" value="4"> Other
</label>
</li>
</ul>
这是因为您在包含
复选框的标签上绑定事件,并且您正在使用for=“chekbox\u id”
。因此,将为标签
以及复选框
触发事件
<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[for*=test_] > input').on('click',function(){
$('div#target').append($(this).parent().clone());
});
要解释发生了什么:
- 单击输入,但是由于标签是使用
for
属性绑定到该输入的,并且只是作为它的子元素,所以这里是您的第一个注册事件李>
- 然后,输入将单击(所有元素传播单击)向下传播到标签,由于标签是您的委托元素,因此将触发第二个事件李>
由于您将输入复选框包装在标签元素中,
实际上,您可以在输入上收听以下内容:
$('label[for*=test_] input').on('click',function(){
$('div#target').append($(this).closest("label").clone());
});
然后克隆父标签
$("label:input").on("click", function( evt ) {
evt.stopPropagation();
});
$('label[for*=test_]').on('click',function(){
$('div#target').append($(this).clone());
});
防止标签和内部输入之间的兄弟关系的另一种方法是停止输入以传播事件,让边界标签>>复选框进入其作业:
$("label:input").on("click", function( evt ) {
evt.stopPropagation();
});
$('label[for*=test_]').on('click',function(){
$('div#target').append($(this).clone());
});
否则,您可以阻止默认标签的行为
这会从绑定的输入中触发回事件,并且正在使用e.preventDefault()
,但是您的(隐藏的)输入复选框将不会被选中强>
$('label[for*=test_]').on('click',function( e ){
e.preventDefault();
$('div#target').append($(this).clone());
});
你可以试试这个
$("label").find("*").click(function( event ) {
event.stopPropagation();
});
$('label[for*=test_]').on('click',function(){
$(this).toggleClass('test');
});
调用标签的单击处理程序两次的原因:
单击与输入关联的标签会触发两个单击事件。将为标签触发第一次单击事件。该单击事件的默认处理会导致关联输入触发第二个单击事件。由于您将输入作为标签的子体,因此第二次单击事件将冒泡到标签。这就是为什么单击事件处理程序会被调用两次
如果您真的想处理标签的点击事件(并且一次点击只执行一次):
(1) 如果愿意并且能够修改HTML,可以移动输入,使其不是标签的后代。仍然会有两个单击事件,但第二个单击事件不会从输入冒泡到标签,因为标签不再是输入的祖先
$('input:checkbox').on('click', function(event) {
event.stopPropagation();
});
$('label[for*=test_]').on('click', function() {
$(this).toggleClass('testing');
});
如果输入不是标签的后代,则必须使用标签的“for”属性将其与输入关联。“for”属性的值应该是输入的“id”值。(您已经包含了具有正确值的“for”属性。)
(3) 相反,您可以阻止第二次单击事件从输入中冒泡出来
$('input:checkbox').on('click', function(event) {
event.stopPropagation();
});
$('label[for*=test_]').on('click', function() {
$(this).toggleClass('testing');
});
注意:如果输入不是标签的子项,则不需要这样做
(4) 或者可以检查处理程序中的事件目标。它将是第一次单击事件的标签,第二次单击事件的输入。以下处理程序仅对第一次单击事件执行if语句中的代码
$('label[for*=test_]').on('click', function(event) {
if (event.target == this) {
$(this).toggleClass('testing');
}
});
注意:如果输入不是标签的子项,上面的代码仍然可以工作,但是If语句是不必要的,因为为输入触发的click事件不会出现在标签上
处理输入的点击:
在您的情况下,实际上不需要为label元素注册click处理程序。您可以为输入注册一个单击(或更改)处理程序。然后,您可以使用$(this).closest('label')
来获取label元素
$('input[name=offering_cycle]').on('click', function() {
$(this).closest('label').toggleClass('testing');
});
注意:如果输入不是标签的子项,则单击标签时仍会调用上面的处理程序,但$(this)。最接近的('label')
不会获取标签。您必须使用类似于$('label[for=“”+this.id+”)
关于标签元素上的“for”属性:
由于标签中有输入,因此不必在标签上包含
for
属性,但这并不是无效的
您已经将“for”属性值设置为输入元素的“id”属性值。这是使用“for”属性将标签与输入关联的正确方法。如果要包含具有无效值的“for”属性,则即使输入是标签的后代,标签也不会与输入关联
从标签元素的“for”属性的:
<
$('label[for*=test_]').on('click', function(event) {
event.preventDefault();
$(this).toggleClass('testing');
// returning false would be another way to prevent the default handling.
});
$('input:checkbox').on('click', function(event) {
event.stopPropagation();
});
$('label[for*=test_]').on('click', function() {
$(this).toggleClass('testing');
});
$('label[for*=test_]').on('click', function(event) {
if (event.target == this) {
$(this).toggleClass('testing');
}
});
$('input[name=offering_cycle]').on('click', function() {
$(this).closest('label').toggleClass('testing');
});