简体   繁体   English

document.querySelectorAll 奇怪的行为

[英]document.querySelectorAll Weird Behaviour

I have a simple HTML like below and corresponding java script code.我有一个简单的 HTML 和相应的 java 脚本代码。

The issue is:问题是:

For .clear and .result buttons, two event listeners are getting attached and called (storeInput as well as their actual listener).对于.clear.result按钮,两个事件侦听器被附加和调用(storeInput 以及它们的实际侦听器)。 Actually, storeInput should not be get called in this case实际上,在这种情况下不应调用storeInput

To debug issue, I commented out below two lines:为了调试问题,我在下面两行注释掉:

//document.querySelector(".clear").addEventListener('click',clear); //document.querySelector(".clear").addEventListener('click',clear); //document.querySelector(".result").addEventListener('click',calculate); //document.querySelector(".result").addEventListener('click',calculate);

So there are no event listeners for .clear and .result buttons But still, storeInput listener gets called if they are clicked因此, .clear.result按钮没有事件侦听器但是,如果单击它们,仍然会调用storeInput listener

Question is:问题是:

why document.querySelectorAll(".digit") and document.querySelectorAll(".operator") are adding event listeners to .clear and .result buttons as well?为什么document.querySelectorAll(".digit")document.querySelectorAll(".operator")也将事件侦听器添加到.clear.result按钮?

 function storeInput() { console.log('storeInput'); } function clear() { console.log('clear'); } function calculate() { console.log('calculate'); } const digits = document.querySelectorAll(".digit"); digits.forEach(function() { this.addEventListener('click', storeInput); }); const operators = document.querySelectorAll(".operator"); operators.forEach(function() { this.addEventListener('click', storeInput); }) document.querySelector(".clear").addEventListener('click', clear); document.querySelector(".result").addEventListener('click', calculate);
 <input type="text" /> <br/> <input type="button" class="digit" value="0" /> <input type="button" class="digit" value="1" /> <input type="button" class="digit" value="2" /> <input type="button" class="digit" value="3" /> <br/> <input type="button" class="digit" value="4" /> <input type="button" class="digit" value="5" /> <input type="button" class="digit" value="6" /> <input type="button" class="digit" value="7" /> <br/> <input type="button" class="digit" value="8" /> <input type="button" class="digit" value="9" /> <br/> <input type="button" class="clear" value="C" /> <br/> <input type="button" class="operator" value="+" /> <input type="button" class="operator" value="-" /> <input type="button" class="operator" value="/" /> <input type="button" class="operator" value="*" /> <br/> <input type="button" class="result" value="=" />

In forEach , this has no special meaning, so what you're really doing is attaching those handlers to window , since this defaults to window in loose mode.forEach中, this没有特殊含义,因此您真正要做的是将这些处理程序附加到window ,因为this在松散模式下默认为window (You may have seen jQuery code using each ; jQuery sets this to each element in an each callback, but forEach doesn't work that way.) (您可能已经看到使用each的 jQuery 代码;jQuery 将this设置为each回调中的每个元素,但forEach不能那样工作。)

To use the element within the forEach callback, accept the element as a parameter and use that parameter, see *** comments:要在forEach回调中使用该元素,请接受该元素作为参数并使用该参数,请参阅***注释:

 function storeInput() { console.log('storeInput'); } function clear() { console.log('clear'); } function calculate() { console.log('calculate'); } const digits = document.querySelectorAll(".digit"); digits.forEach(function(el) { // *** Note the parameter `el` el.addEventListener('click', storeInput); // ^ note using the parameter }); const operators = document.querySelectorAll(".operator"); operators.forEach(function(el) { // *** Note the parameter `el` el.addEventListener('click', storeInput); // ^ note using the parameter }) document.querySelector(".clear").addEventListener('click', clear); document.querySelector(".result").addEventListener('click', calculate);
 <input type="text" /> <br/> <input type="button" class="digit" value="0" /> <input type="button" class="digit" value="1" /> <input type="button" class="digit" value="2" /> <input type="button" class="digit" value="3" /> <br/> <input type="button" class="digit" value="4" /> <input type="button" class="digit" value="5" /> <input type="button" class="digit" value="6" /> <input type="button" class="digit" value="7" /> <br/> <input type="button" class="digit" value="8" /> <input type="button" class="digit" value="9" /> <br/> <input type="button" class="clear" value="C" /> <br/> <input type="button" class="operator" value="+" /> <input type="button" class="operator" value="-" /> <input type="button" class="operator" value="/" /> <input type="button" class="operator" value="*" /> <br/> <input type="button" class="result" value="=" />


Another option is to put a container around the digits, and another container around the operators, and just handle clicks on those containers, using the target property of the event object to see which digit or operator was clicked.另一种选择是在数字周围放置一个容器,在运算符周围放置另一个容器,并仅处理对这些容器的点击,使用事件 object 的target属性来查看单击了哪个数字或运算符。

 function storeInput(e) { console.log('storeInput: ' + e.target.value); } function clear() { console.log('clear'); } function calculate() { console.log('calculate'); } document.querySelector(".digits").addEventListener('click', storeInput); document.querySelector(".operators").addEventListener('click', storeInput); document.querySelector(".clear").addEventListener('click', clear); document.querySelector(".result").addEventListener('click', calculate);
 <input type="text" /> <div class="digits"> <input type="button" class="digit" value="0" /> <input type="button" class="digit" value="1" /> <input type="button" class="digit" value="2" /> <input type="button" class="digit" value="3" /> <br/> <input type="button" class="digit" value="4" /> <input type="button" class="digit" value="5" /> <input type="button" class="digit" value="6" /> <input type="button" class="digit" value="7" /> <br/> <input type="button" class="digit" value="8" /> <input type="button" class="digit" value="9" /> </div> <input type="button" class="clear" value="C" /> <div class="operators"> <input type="button" class="operator" value="+" /> <input type="button" class="operator" value="-" /> <input type="button" class="operator" value="/" /> <input type="button" class="operator" value="*" /> </div> <input type="button" class="result" value="=" />

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

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