i'm getting an error that addeventlistener is not a function. i try to put it into a function but it didn't work. i also did this with btn.onclick event but i was getting the error that "Uncaught TypeError: Cannot set property 'onclick'".
any idea how to fix this, and why am i getting this error.
here is the code -
<!-- 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>
CodePudding user response:
querySelectorAll
returns a collection of node elements. If you have multiple elements that match you selector you have to iterate over this collection and set the listener for each element. If you are sure there is only one element that matches the selector you can use querySelector
to get the first element that matches. Then you can set the listener directly to the element.
CodePudding user response:
Your btn
is an array of node (your buttons), you can't do and addEventListener
on a array? You need first to make a true array like that:
var btn = [...slc('.combine_')]
And then loop the array and create the events listener, like that :
for(let i=0; i<btn.length; i ){
btn[i].addEventListener("click", ()=>{})
}
CodePudding user response:
As previously noted querySelectorAll
will return a nodelist rather than a specific node and thus assigning an event listener as you do will not work. Instead the nodelist should be iterated through and the event listener applied to each node. The idea of using a shortcut to document.querySelectorAll
is one I do frequently but they are a little different as shown below. The remains of the code can be simplified a little ...
(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>