开发者问题收集

如何修复.addeventListener不是一个函数[重复]

2021-10-01
1954

我收到一个错误,提示 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>
3个回答

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

Jonas Weinhardt
2021-10-01

如前所述, querySelectorAll 将返回一个节点列表,而不是一个特定的节点,因此像您那样分配事件侦听器将不起作用。相反,应该迭代节点列表并将事件侦听器应用于每个节点。使用 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>
Professor Abronsius
2021-10-01

您的 btn 是一个节点数组(您的按钮),您不能在数组上执行 addEventListener 吗?您需要先创建一个真正的数组,如下所示:

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

然后循环数组并创建事件侦听器,如下所示:

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