如何修复 .addEventListener 不是函数

How to fix .addEventListener is not a function

我收到一条错误消息,提示 addeventlistener 不是一个函数。我尝试将它放入一个函数中,但它没有用。我也用 btn.onclick 事件做了这个,但我得到了错误:

"Uncaught TypeError: Cannot set property 'onclick'".

知道如何解决这个问题吗?为什么会出现此错误?

代码如下:

<!-- try run this -->

<div class="input_wrpr">
      <input class="enter_1" type="number" />
      <input class="enter_2" type="number" />
      <button data-combine="plus" class="combine_ plus" type="submit"> + </button>
      <button data-combine="minus" class="combine_ minus" type="submit"> - </button>
      <button data-combine="multi" class="combine_ multi" type="submit"> * </button>
      <button data-combine="divi" class="combine_ divi" type="submit"> / </button>
      <p class="result_"></p>
    </div>

    <script>
      (function () {
        "use strict";
        var slc = (elemnt) => { 
          return document.querySelectorAll(elemnt);
        };
        var view = slc(".result_"),
          btn = slc(".combine_"),
          input1 = slc(".enter_1"),
          input2 = slc(".enter_2");
          
          btn.addEventListener("click", (e) => {
            view.innerHTML = parseInt(input1.value) + parseInt(input2.value);
          });
      })();  // i know this code is not complete but i'm having an issue with eventlistener// i try this using loop but it's not working i mean i'm not getting any errors but result is not printing/
      
     // i didn't try this using getAttribute because i don't know how to do with that especially with data- attribute.
      

// * this below code is working fine but i wanted to shorteren this code 
// * i gusse you alredy have seen it that here i have to give eventlistener to each button and i'm using querySelector but above i'm using querySelectorAll. 

      // (function () {
      //   "use strict";
      //   var slc = (elemnt) => {
      //     return document.querySelector(elemnt);
      //   };
      //   var view = slc(".result_"),
      //     plus = slc(".plus"),
      //     minus = slc(".minus"),
      //     multi = slc(".multi"),
      //     divi = slc(".divi"),
      //     input1 = slc(".enter_1"),
      //     input2 = slc(".enter_2");
      
      //   plus.addEventListener("click", (e) => {
      //     view.innerHTML = parseInt(input1.value) + parseInt(input2.value);
      //     input1.value = "";
      //     input2.value = "";
      //   });
      //   minus.addEventListener("click", (e) => {
      //     view.innerHTML = parseInt(input1.value) - parseInt(input2.value);
      //     input1.value = "";
      //     input2.value = "";
      //   });
      //   multi.addEventListener("click", (e) => {
      //     view.innerHTML = parseInt(input1.value) * parseInt(input2.value);
      //     input1.value = "";
      //     input2.value = "";
      //   });
      //   divi.addEventListener("click", (e) => {
      //     view.innerHTML = parseInt(input1.value) / parseInt(input2.value);
      //     input1.value = "";
      //     input2.value = "";
      //   });
      // })();

    </script>

querySelectorAll returns 节点元素的集合。如果您有多个与您的选择器匹配的元素,则必须遍历此集合并为每个元素设置侦听器。如果您确定只有一个元素与选择器匹配,您可以使用 querySelector 来获取第一个匹配的元素。然后就可以直接给元素设置监听了。

你的btn是一个节点数组(你的按钮),你不能在一个数组上做and addEventListener?你首先需要像这样制作一个真正的数组:

var btn = [...slc('.combine_')]

然后循环数组并创建事件侦听器,就像这样:

for(let i=0; i<btn.length; i++){
  btn[i].addEventListener("click", ()=>{})
}

如前所述,querySelectorAll 将 return 一个节点列表而不是一个特定的节点,因此像您一样分配一个事件侦听器将不起作用。相反,应该遍历节点列表并将事件侦听器应用于每个节点。使用 document.querySelectorAll 的快捷方式的想法是我经常做的,但它们有点不同,如下所示。剩下的代码可以稍微简化一下...

(function () {
  "use strict";
  
  var q=(e,n=document)=>n.querySelector(e);
  var qa=(e,n=document)=>n.querySelectorAll(e);
  var view = q(".result_");
  var btns = qa(".combine_");
  
  let clickhandler=(e)=>{
    e.preventDefault();
  
    let a=Number( q(".enter_1").value );
    let b=Number( q(".enter_2").value );
    let c;
    
    switch(e.target.dataset.combine){
      case 'plus':c=a+b;break;
      case 'minus':c=a-b;break;
      case 'multi':c=a*b;break;
      case 'divi':c=a/b;break;
    }
    view.textContent=c.toString();
  };
  
  
  
  btns.forEach( btn=>btn.addEventListener("click", clickhandler ) );
})();
<!-- try run this -->

<div class="input_wrpr">
      <input name='a' class="enter_1" type="number" />
      <input name='b' class="enter_2" type="number" />
      
      <button data-combine="plus" class="combine_ plus" type="submit"> + </button>
      <button data-combine="minus" class="combine_ minus" type="submit"> - </button>
      <button data-combine="multi" class="combine_ multi" type="submit"> * </button>
      <button data-combine="divi" class="combine_ divi" type="submit"> / </button>
      
      <p class="result_"></p>
</div>