即使使用stopPropagation,Javascript单击事件也会触发两次

时间:2016-04-06 20:37:39

标签: 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>

其中大约有13个。我想在点击时向标签添加一个类。但是,click事件会触发两次。现在我正在调试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发射两次。

4 个答案:

答案 0 :(得分:3)

尝试在stopPropogation之后添加preventDefault:

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

我认为最好在stopPropogation&amp;之后放置console.log(e)。虽然阻止默认。然后,您还需要实现将复选框设置为已选中的功能,因为这样可以防止这种情况发生。

答案 1 :(得分:3)

您正在向标签添加事件侦听器,您应该将事件侦听器添加到复选框,因为标签行为会复制中为指定的输入相同。

请注意,如果您单击复选框中的回调即可正常工作,这是因为复选框引发了标签上的事件。

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

答案 2 :(得分:0)

<span><img>收到“点击”事件时,会将DOM冒泡到<label>元素,并调用您的事件处理程序。 <label>然后在<input>元素上触发另一个“点击”事件,并且还会冒充<label>

您可以签入处理程序以查看是否点击了<input>

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

    // do stuff
}

或者,您只需将“click”处理程序添加到<input>本身。

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

[].forEach.call(cars, function(car) {
    car.addEventListener("click", function(e){
        selectVehicle(car,e);
    }, false);
});

答案 3 :(得分:0)

您不需要阻止默认或停止传播,只需在输入元素上添加列表器。

  

cars [c] .children [0] .addEventListener(&#34; click&#34;,function(e){

试试这个。它按预期工作。

此外,如果标签元素包含所需的输入/其他元素,则不需要使用带有标签的标识符#s

&#13;
&#13;
var cars = document.getElementsByClassName('cars');

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

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

}
&#13;
<label class="cars">
  <input type="checkbox" value="1" alt="Cadenza" name="vehicles[]">
  <img src="img/bill_murray_173x173.jpg">
  <span>Cadenza</span>
</label>
<label class="cars">
  <input type="checkbox" value="1" alt="Cadenza" name="vehicles[]">
  <img src="img/bill_murray_173x173.jpg">
  <span>Cadenza 2</span>
</label>
&#13;
&#13;
&#13;