Переменная область действия и обратный вызов слушателей событий

У меня есть следующий код, который работает сейчас. Вопрос почему?

    let resizing = false
    let startX = 0
    let startY = 0
    window.addEventListener('mousedown', (e) => {
      resizing = true
      startX = e.clientX
      startY = e.clientY
      console.log('startX ' + startX)
      document.body.addEventListener('mouseup', (e) => {
        if (resizing) {
          let endX = e.screenX
          console.log('endX ' + endX)
          let endY = e.screenY
          this.resize(startX, endX, startY, endY, window)
        }
        resizing = false
        e.target.removeEventListener('mouseup', window)
      })
    })

Ранее я определил мой startX а также startY внутри обратного вызова mouseup вот так:

    let resizing = false
    window.addEventListener('mousedown', (e) => {
      resizing = true
      let startX = e.clientX
      let startY = e.clientY
      console.log('startX ' + startX)
      document.body.addEventListener('mouseup', (e) => {
        if (resizing) {
          let endX = e.screenX
          console.log('endX ' + endX)
          let endY = e.screenY
          this.resize(startX, endX, startY, endY, window)
        }
        resizing = false
        e.target.removeEventListener('mouseup', window)
      })
    })

Но я получал одинаковые значения для startX и startY каждый раз, когда событие запускалось после первого раза. Зачем? Это не имеет смысла для меня, поскольку область действия let должна иметь переменную, сбрасываемую каждый раз, когда выполняется функция обратного вызова для события mouseup?

Я обновил свой код в соответствии с комментариями Таплара, и теперь область работает так, как я ожидал

let window = this
window.addEventListener('mousedown', (e) => {
  let startX = e.clientX
  let startY = e.clientY
  console.log('startX ' + startX)
  var mouseUpHandler = function (e) {
    console.log('mouseup')
    let endX = e.screenX
    console.log('endX ' + endX)
    let endY = e.screenY
    window.resize(startX, endX, startY, endY, window)
    document.body.removeEventListener('mouseup', mouseUpHandler)
  }
  document.body.addEventListener('mouseup', mouseUpHandler)
})
  }

1 ответ

Решение

Ваша оригинальная логика e.target.removeEventListener('mouseup', window), где e.target решает в document.body, Так что это эффективно выполняет:

document.body.removeEventListener('mouseup', window);

Одна проблема здесь заключается в том, что второй аргумент, который передается в removeEventListener() Метод, как ожидается, будет одним из методов, которые вы ранее прикрепили. Ссылка https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener

Учитывая, что вы проходите в window, который не является одним из методов, которые вы ранее прикрепили (и при этом он вообще не является методом), я предполагаю, что логика либо проверяет, что параметр не является функцией, и ничего не делает, либо пытается удалить его видит, что он не соответствует ни одному из прикрепленных методов, и просто ничего не делает. Это, однако, предположение.

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

Вы можете проверить это, изменив параметр обратно на окно, и если проблема появится снова, это в значительной степени подтвердит это предположение.

Другие вопросы по тегам