简体   繁体   English

Javascript条件点击事件多次运行

[英]Javascript conditional click event running multiple times

I have an HTML select that is meant to influence my Javascript click event. 我有一个HTML选择,它会影响我的Javascript点击事件。 While my code technically works, I am unsure why my click event runs in the corresponding times that I change my select box value. 尽管我的代码在技术上可以正常工作,但是我不确定为什么单击事件在更改选择框值的相应时间运行。

Say I change the option select to anything that isn't -- . 假设我将select选项更改为非-- If I then click on the text labeled donate then on my console log there is a text Michael . 如果然后我单击标记为donate的文本,则在控制台日志上将显示Michael文本。 Now, if I switch the option value to another value that isn' t -- , and click on donate again, then my console runs my click event 2 times. 现在,如果我将选项值切换为不是--另一个值,然后再次单击donate ,那么控制台将两次运行click事件。 And if I repeat this process again my click event runs 3 times. 如果我再次重复此过程,我的点击事件将运行3次。

My example is going to seem a bit nonsensical, but hopefully the point is clear. 我的例子似乎有点荒谬,但希望这一点很明确。

 var changing = document.getElementById("changing"); var donate = document.getElementsByClassName("donate"); changing.addEventListener('change', function() { if (this.value !== "--") { for (i = 0; i < donate.length; i++) { donate[i].addEventListener('click', function() { console.log("Michael"); }); } } }); 
 <select id="changing"> <option value="--">--</option> <option value="vegetarian">Vegetarian</option> <option value="technical">Technical</option> <option value="shoes">Shoes</option> </select> <p class="donate">Donate</p> <p class="donate">Donate</p> <p class="donate">Donate</p> 

To clarify, if I do an option change once, then clicking on any donate text leads to my console adding the text Michael one time. 为了澄清,如果我一次更改选项,那么单击任何donate文本都会导致我的控制台一次添加文本Michael If I change it again, it multiplies this into 2, leading to 3 shows of Michael . 如果我再次更改它,它将把它乘以2,从而得到Michael 3场演出。 Change again, and it adds 3, leading to 6 times console logging Michael . 再次更改,它增加3,导致控制台记录Michael次数达到6倍。

This indicates to me that my function is running these many times whenever I click on the donate text. 这向我表明,每当我单击donate文本时,我的函数就会多次运行。 How would I reformat to where my function is only run once after each option change? 如何在每次更改选项后重新格式化仅运行一次功能的位置? Or is there something fundamental that I am completely missing? 还是我完全想不到的基本原则?

Is this closer to what you are trying to accomplish? 这与您要完成的目标更接近吗?

var changing = document.getElementById("changing");
var donate = document.getElementsByClassName("donate");
var flag = false;

function log() {
    console.log("Michael");
}

changing.addEventListener('change', function() {
  if (this.value !== "--" && !flag) {
    flag = true;
    for (i = 0; i < donate.length; i++) {
      donate[i].addEventListener('click', log );
    }
  }
  else if(this.value == "--") { 
    flag = false;
    console.log("+++")
    for (i = 0; i < donate.length; i++) {
      donate[i].removeEventListener('click', log );
    }
  }
});

.

<select id="changing">
    <option value="--">--</option>
    <option value="vegetarian">Vegetarian</option>
    <option value="technical">Technical</option>
    <option value="shoes">Shoes</option>
</select>
<p class="donate">Donate</p>
<p class="donate">Donate</p>
<p class="donate">Donate</p>

Note, event listeners need to be attached only once. 请注意,事件侦听器仅需要附加一次。 So, consider what it is the code is actually trying to accomplish. 因此,请考虑代码 实际上试图完成的任务。

You're binding a new click listener every time you call addEventListener every time the change listener is triggered if the select value is == . 如果选择值为==则每次触发change侦听器时,每次调用addEventListener都将绑定一个新的click侦听器。

If you want Michael to be printed only once if the select value is == , then bind all click listeners once, and check for the value inside it. 如果希望在选择值为==仅将Michael打印一次,则将所有click侦听器绑定一次,并检查其中的值。

for (let i = 0; i < donate.length; i++) {
  donate[i].addEventListener("click", function() {
    if (changing.value !== "--") {
      console.log("Michael");
    }
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM