Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么onclick会被触发两次?_Javascript_Jquery - Fatal编程技术网

Javascript 为什么onclick会被触发两次?

Javascript 为什么onclick会被触发两次?,javascript,jquery,Javascript,Jquery,这是我一直在研究的一小段代码: 我只想在单击同一元素时添加一个active类作为标签,并保持默认行为不变 我不知道为什么点击事件会被触发两次 $('label.add to favorite')。单击(函数(e){ 警报(“此处”); $(this.toggleClass('active'); }); 。添加到收藏夹span{ 光标:指针; 颜色:#d2d6de; } .添加到收藏夹:悬停span、.add-to-favorite.active span{ 颜色:#CB3D3D; }

这是我一直在研究的一小段代码:

我只想在单击同一元素时添加一个
active
类作为标签,并保持默认行为不变

我不知道为什么点击事件会被触发两次

$('label.add to favorite')。单击(函数(e){
警报(“此处”);
$(this.toggleClass('active');
});
。添加到收藏夹span{
光标:指针;
颜色:#d2d6de;
}
.添加到收藏夹:悬停span、.add-to-favorite.active span{
颜色:#CB3D3D;
}


同时删除警报

$('label.add-to-favourite').on("click",function(e){
  $(this).toggleClass('active');
});

单击标签时,会触发复选框的单击事件

但是,单击标签也会自动向关联的输入元素发送单击事件,因此这被视为单击复选框。然后,事件冒泡导致在包含元素(即标签)上触发click事件,从而再次运行处理程序

将复选框置于标签外,如下所示

<label></label>
<input type="checkbox">


更新:您也可以按照@Rejith R Krishnan的建议,在复选框上设置单击事件处理程序,而不是标签

删除单击的绑定,然后添加
将事件绑定更改为
复选框

$('label.add-to-favorite:checkbox')。更改(函数(e){
警报(“此处”);
$(this.toggleClass('active');
});
。添加到收藏夹span{
光标:指针;
颜色:#d2d6de;
}
.添加到收藏夹:悬停span、.add-to-favorite.active span{
颜色:#CB3D3D;
}
.hide{display:none;}


只需定义目标元素类型,就可以了

$('label.add to favorite')。单击(函数(e){
if(e.target.type=='checkbox'){
警报(“此处”);
$(this.toggleClass('active');
}
});
。添加到收藏夹span{
光标:指针;
颜色:#d2d6de;
}
.添加到收藏夹:悬停span、.add-to-favorite.active span{
颜色:#CB3D3D;
}


这是事件传播的情况。请尝试此方法

$('label.add-to-favourite').click(function(e){
  alert("here");
  $(this).toggleClass('active');
 e.preventDefault();
});
您可以尝试以下代码:

$('label.add-to-favourite').click(function(e){
    e.preventDefault();
    var $check = $(':checkbox', this);
    $check.prop('checked', !$check.prop('checked'));
    alert("here");
    $(this).toggleClass('active');
});
它将添加类并选中复选框

例如:

我不知道为什么点击事件会被触发两次

我想说,
label
元素是
复选框的父元素,因此它们之间存在连接。当您单击标签时,单击“发生在”复选框也会出现事件气泡,因此会导致两个警报

要么将复选框从标签中去掉,要么仅通过css即可实现

一个结构变化不大的例子

$('label.add to favorite')。单击(函数(e){
警报(“此处”);
$(this.toggleClass('active')。同级(':checkbox').prop('checked'),$(this.hasClass('active'))
});
。添加到收藏夹span{
光标:指针;
颜色:#d2d6de;
}
。添加到收藏夹:悬停范围,
.add-to-favorite.active span{
颜色:#CB3D3D;
}


我添加警报只是为了显示事件被触发了两次。我建议只更改OP侦听的元素,而不是重新定位复选框(如果按照您的说明操作,会破坏它们之间的可访问性连接)。好的,我明白了。但是有没有一种方法可以做到这一点而不改变HTML?是的,您可以按照@Rejith R Krishnan的建议进行操作,并在checkbox@AngryCoder:是:收听
点击复选框上的
,而不是标签。实际上,Rejith建议使用
更改
。这可能现在起作用了。(很多年前,它没有出现在一些浏览器上,直到focus离开复选框才启动它…)我已经尝试过了。这将阻止元素的默认行为,并且复选框不会被选中。请参阅有关此行为的信息:
例如,在单击复选框标签可选中复选框的平台上,单击以下代码段中的标签可能会触发用户代理在输入元素上运行合成单击激活步骤,就好像元素本身是由用户触发的:在其他平台上丢失了,行为可能只是为了集中控件,或者什么也不做。