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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.