Ошибка "TypeError: Cannot read properties of undefined" [при попытке вынести объект события на глобальный уровень]

Пытался решить эту ошибку с помощью глобальной переменной, но результата особо нету.

const calculator = document.querySelector(".calculator");
const keys = calculator.querySelector(".calculator__keys")

keys.addEventListener("click", e => {
    if (e.target.matches("button")){}
    
})
// в переменной "e" значение undefined и из-за этого появляеться ошибка

const key = e.target
const action = key.dataset.action

if (!action){
    console.log("number key!")
}

if (
    action === 'add' ||
    action === 'subtract' ||
    action === 'multiply' ||
    action === 'divide'
){
    console.log('operator key!')
}

if (action === 'decimal') {
    console.log('decimal key!')
}
  
if (action === 'clear') {
    console.log('clear key!')
}
  
if (action === 'calculate') {
    console.log('equal key!')
}

const display = document.querySelector('.calculator__display')

keys.addEventListener('click', e => {
  if (e.target.matches('button')) {
    const key = e.target
    const action = key.dataset.action
    const keyContent = key.textContent
    const displayedNum = display.textContent
  }
})

if (!action) {
    if (displayedNum === '0') {
      display.textContent = keyContent
    }
  }

if (!action) {
    if (displayedNum === '0') {
      display.textContent = keyContent
    } else {
      display.textContent = displayedNum + keyContent
    }
  }  

if (action === 'decimal') {
    display.textContent = displayedNum + '.'
  }

if (
  action === 'add' ||
  action === 'subtract' ||
  action === 'multiply' ||
  action === 'divide'
) {
  key.classList.add('is-depressed')
}

keys.addEventListener('click', e => {
    if (e.target.matches('button')) {
      const key = e.target
      // ...
      
      // Remove .is-depressed class from all keys
      Array.from(key.parentNode.children)
        .forEach(k => k.classList.remove('is-depressed'))
         calculator.dataset.previousKeyType = 'operator'
    }
  })
  
  const previousKeyType = calculator.dataset.previousKeyType

  if (!action) {
    if (displayedNum === '0' || previousKeyType === 'operator') {
      display.textContent = keyContent
    } else {
      display.textContent = displayedNum + keyContent
    }
  }

Все верно. На этом этапе выполнения кода e содержит undefined, или вообще может быть не определена.

Этот код, использующий e надо перенести внутри коллбека-обработчика события click, и код задаработает. Заработает потому что код обработчика вызывается после пользовательского клика, и вызывается в объектом-аргументом который записан в переменную e. Проблема с undeined должна смениться скорее всего иной проблемой.

В целом задачу того что в каком-то коллбеке, выполняющемся на действие пользователя или через интервал, есть значение а мы хотим это значение в другом месте, не решить через глобальную переменную. Нужны другие подходы, нужно переносить свой код обработки данных доступных в коллбеке, обычно в виде функции, туда где есть данные, т.е. внутрь коллбека.

Новый вид кода будет выглядеть так. Наверняка в нем будут проблемы, но это уже другие проблемы.

keys.addEventListener("click", e => {
  const key = e.target
  const action = key.dataset.action

  if (!action){
      console.log("number key!")
  }

  if (
      action === 'add' ||
      action === 'subtract' ||
      action === 'multiply' ||
      action === 'divide'
  ){
      console.log('operator key!')
  }

  if (action === 'decimal') {
      console.log('decimal key!')
  }
    
  if (action === 'clear') {
      console.log('clear key!')
  }
    
  if (action === 'calculate') {
      console.log('equal key!')
  }
}) 
1 лайк

Благодарю за помощь👍, конечно появились другие ошибки, но над ними я буду работать сам, просто именно эту я не мог нормально решить

1 лайк