Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.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点击事件触发两次,即使使用StopRopagation_Javascript_Addeventlistener - Fatal编程技术网

Javascript点击事件触发两次,即使使用StopRopagation

Javascript点击事件触发两次,即使使用StopRopagation,javascript,addeventlistener,Javascript,Addeventlistener,我有一套类似这样的项目: <label for="Cadenza-1" class="cars"> <input type="checkbox" value="1" alt="Cadenza" id="Cadenza-1" name="vehicles[]"> <img src="img/bill_murray_173x173.jpg"> <span>Cadenza</span> </label>

我有一套类似这样的项目:

<label for="Cadenza-1" class="cars">
    <input type="checkbox" value="1" alt="Cadenza" id="Cadenza-1" name="vehicles[]">
    <img src="img/bill_murray_173x173.jpg">
    <span>Cadenza</span>
</label>
大约有13个。我想在单击时向标签添加一个类。但是,单击事件会触发两次。现在我正在调试click事件,然后我将添加类:

var cars = document.getElementsByClassName('cars');

for(var c = 0;c < cars.length; c++){
    cars[c].addEventListener("click", function(e){
        selectVehicle(cars[c],e);
    },false);
}

function selectVehicle(el,e) {
    console.log(e);
    e.stopPropagation();
}

console.log会触发两次。

尝试在stopPropogation之后添加preventDefault:

function selectVehicle(el,e) {
    console.log(e);
    e.stopPropagation();
    e.preventDefault();
}

我认为最好将console.loge放在stopPropogation和preventDefault之后。然后,您还需要实现将复选框设置为选中的功能,因为这将防止这种情况发生

尝试在stopPropogation之后添加preventDefault:

function selectVehicle(el,e) {
    console.log(e);
    e.stopPropagation();
    e.preventDefault();
}
我认为最好将console.loge放在stopPropogation和preventDefault之后。然后,您还需要实现将复选框设置为选中的功能,因为这将防止这种情况发生

当或接收到一个click事件时,会将DOM冒泡到元素,并调用事件处理程序。然后,会在元素上触发另一个单击事件,该事件也会冒泡到

您可以检入处理程序以查看是否已单击:

function selectVehicle(el,e) {
    if (e.target.tagName !== "INPUT") return;

    // do stuff
}
或者,您可以只将click处理程序添加到其自身

现在您还将注意到,您的代码无法工作,因为您遇到了循环内绑定事件处理程序的常见问题。问题是,变量c的值是事件处理程序实际运行时cars列表的长度。有几种方法可以解决这个问题;一种是使用forEach循环,而不是for循环:

当或接收到一个click事件时,这将使DOM冒泡到元素,并且将调用事件处理程序。然后,会在元素上触发另一个单击事件,该事件也会冒泡到

您可以检入处理程序以查看是否已单击:

function selectVehicle(el,e) {
    if (e.target.tagName !== "INPUT") return;

    // do stuff
}
或者,您可以只将click处理程序添加到其自身

现在您还将注意到,您的代码无法工作,因为您遇到了循环内绑定事件处理程序的常见问题。问题是,变量c的值是事件处理程序实际运行时cars列表的长度。有几种方法可以解决这个问题;一种是使用forEach循环,而不是for循环:


如果要将事件侦听器添加到标签中,则应将事件侦听器添加到复选框中,因为标签行为复制了为中指定的相同输入

请注意,如果只在复选框中单击,回调工作正常,这是因为标签上的事件是由复选框引发的


正确的方法是仅为复选框添加事件侦听器,或在setlectVehicle回调中添加prevent default。

如果要将事件侦听器添加到标签,则应将事件侦听器添加到复选框,因为标签行为复制了为中指定的相同输入

请注意,如果只在复选框中单击,回调工作正常,这是因为标签上的事件是由复选框引发的


正确的方法是仅为复选框添加事件侦听器,或在SetSelect车辆回调中添加阻止默认值。

您不需要阻止默认值或阻止默认值,只需在输入元素上添加listner即可

cars[c]。子项[0]。addEventListenerclick,函数E{

试试这个。它按预期工作

此外,如果label元素包含所需的输入/其他元素,则不需要将Id与label一起使用 var cars=document.getElementsByClassName'cars'; 对于var C=0;C< CARS长度;C++ { cars[c]。子项[0]。addEventListenerclick,函数E{ 选择车辆卡[c],e; },假; } 功能选择车辆级别,e{ console.loge; } 华彩乐段 华彩乐段2
您不需要阻止default或stopPropagation,只需在输入元素上添加listner即可

cars[c]。子项[0]。addEventListenerclick,函数E{

试试这个。它按预期工作

此外,如果label元素包含所需的输入/其他元素,则不需要将Id与label一起使用 var cars=document.getElementsByClassName'cars'; 对于var C=0;C< CARS长度;C++ { cars[c]。子项[0]。addEventListenerclick,函数E{ 选择车辆卡[c],e; },假; } 功能选择车辆级别,e{ console.loge; } 华彩乐段 华彩乐段2
我相信一个标签已经有了一个click事件。.StopperPagation方法可以防止事件在DOM中冒泡。除非您有其他事件处理程序绑定到包含块元素,否则它实际上不会做任何事情。所有涉及的元素都有唯一的id值吗?另外,在运行代码时,它只在单击时触发一次。.I我猜您可能已经注册了两次事件。标签上已经有一个单击事件
stopPropagation方法防止事件在DOM中冒泡。除非您已将其他事件处理程序绑定到包含块的元素,否则它实际上不会执行任何操作。是否所有涉及的元素都具有唯一的id值?此外,运行代码时,它只在单击时触发一次。我想您可能已注册了两次事件。您的答案正确,但我已调整为查看正在单击的图像,以避免出现默认问题。计时器用完后,我将接受您的答案。您的答案正确,但我已调整为查看正在单击的图像相反,为了避免默认问题。计时器用完后,我将接受您的答案。只处理相关的标记名正是正确的做法!只处理相关的标签名是正确的做法!