0

So I am trying to simply display the numbers/signs written within each 'num' div. Which should be reachable through innerHTML correct? so I have a for loop through all my 'num' divs, with a click listener, though the clicks are returning undefined, instead of each element's innerHTML.

I have also tried (this.innerHTML instead of number[i].innerHTML within the event listener in the loop). to no avail.

I must be missing something, please help.

const screen = document.querySelector('.screen')
const number = document.querySelectorAll('.num')
const opr = document.querySelector('.opr')
const clr = document.querySelector('.clr')


for (i = 0; i < number.length; i++) {
  number[i].addEventListener('click', (e) => {
    screen.innerHTML += number.innerHTML
    console.log(number[i].innerHTML)
    console.log('clicked')
  })
}
<head>
  <link rel="stylesheet" type="text/css" href="src/style.css">
  <title> File Title </title>
  <meta charset="UTF-8">
</head>

<body>

     <div class="calculator">

  <div class="screen">
  </div>
  <div class="inputs">
    <button class="opr add">+</button>
    <button class="opr sub">-</button>
    <button class="opr div">/</button>
    <button class="opr mult">*</button>
    <button class="num">1</button>
    <button class="num">2</button>
    <button class="num">3</button>
    <button class="num">4</button>
    <button class="num">5</button>
    <button class="num">6</button>
    <button class="num">7</button>
    <button class="num">8</button>
    <button class="num">9</button>
    <button class="num">0</button>
    <button class="opr dot">.</button>
    <button class="opr eql">=</button>
    <button class="clr">C</button>
  </div>

</div>
  <script src="src/script.js"></script>
</body>

5
  • Off the top of my head: document.querySelector('.screen') may need to be document.querySelector('.screen')[0] -- querySelector may be returning an array. Also, wrap your variables in Number() -- those might be getting the numbers as strings and your concating strings in screen.innerHTML += number.innerHTML Commented Feb 22, 2021 at 2:45
  • @Coll querySelector only returns the first occurance of an element that matches the selector. querySelectorAll returns an HTMLElementCollection which can be indexed. Commented Feb 22, 2021 at 2:48
  • @HaoWu Yes, thank you. Just looked up .querySelector! Commented Feb 22, 2021 at 2:57
  • I am curious about the missing CSS. (and this is a textbook case for the use of an event delegation ) Commented Feb 22, 2021 at 3:01
  • try to use <butttttton instead of <buttton Commented Feb 22, 2021 at 3:29

3 Answers 3

1

simply do

const
  screen = document.querySelector('.screen')
, number = document.querySelectorAll('.num')
, opr    = document.querySelector('.opr')
, clr    = document.querySelector('.clr')
   

number.forEach(nElm => nElm.onclick = e => screen.textContent += nElm.textContent )

or use event delegation

const
  screen  = document.querySelector('#screen')
, buttons = document.querySelector('#inputs')

buttons.onclick = ({target}) => 
  {
  if (!target.matches('button[data-op]')) return

  switch (target.dataset.op) 
    {
    case 'num':
      screen.textContent += target.textContent.trim()
      break;
    case 'calc':
      screen.textContent += target.textContent
      break;
    case 'clr':
      screen.textContent = ''
      break;
    case 'eql':
      screen.textContent = eval(screen.textContent)
      break;
    }
  }
#screen {
  display : block;
  width   : 200px;
  height  : 20px;
  padding : 10px;
  background-color: aquamarine;
  text-align: right;
}
<div id="calculator">
  <div id="screen"> </div>
  <div id="inputs">
    <button data-op="calc" > + </button>
    <button data-op="calc" > - </button>
    <button data-op="calc" > / </button>
    <button data-op="calc" > * </button> <br>
    <button data-op="num"  > 1 </button>
    <button data-op="num"  > 2 </button>
    <button data-op="num"  > 3 </button>
    <button data-op="num"  > 4 </button>  <br>
    <button data-op="num"  > 5 </button>
    <button data-op="num"  > 6 </button>
    <button data-op="num"  > 7 </button>
    <button data-op="num"  > 8 </button> <br>
    <button data-op="num"  > 9 </button>
    <button data-op="num"  > 0 </button> 
    <button data-op="num"  > . </button>  <br>
    <button data-op="eql"  > = </button>
    <button data-op="clr"  > C </button>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much, data attributes turned out to be the best way to make this work. I would've thought innerHTML would be reachable.
0

I think it will be easier to add id to your buttons and then use "e.target.id" to get the element id and after that the innerhtml

1 Comment

I tried the using ids aswel but it still returned undefined. turns out data attributes work. Although I'd like to know why innerHTML cannot be detected.
0

You forget to use number[i] when concat screen innerHTML:

screen.innerHTML += number.innerHTML;
// correct:
screen.innerHTML += number[i].innerHTML;

And you can use event to get target:

screen.innerHTML += e.target.innerHTML;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.