Почему alert () выполняется, даже если beforeDefault () вызывается до alert ()? - PullRequest
0 голосов
/ 22 сентября 2019

В следующем коде почему alert('Alert on btn is triggered') }) срабатывает, хотя event.preventDefault() вызывается перед этой строкой в ​​обработчике click #btn el.

Кроме того, почему onclick="alerted()не срабатывает на #btn или #wrap div, но срабатывает обратный вызов, прикрепленный к click с addEventListener.

var btn = document.getElementById('btn')
var wrap = document.getElementById('wrap')

btn.addEventListener('click', function() {
  event.stopPropagation()
  if (event.cancelable) {
    event.preventDefault()
  }
  alert('Alert on btn is triggered')
})


function alerted() {
  alert('Alerted fired')
}

wrap.addEventListener('click', function() {
  alert(this.id)
  alert(event.target.tagName + "#" + event.target.id)
})
#wrap {
  padding: 20px;
  border: 1px solid red;
}
<div id="wrap" onclick="alerted">
  <button id="btn" onclick="alerted">Click Me</button>
</div>

Ответы [ 3 ]

6 голосов
/ 22 сентября 2019

Вызов event.preventDefault() или event.stopPropagation не остановит текущий обратный вызов. Неважно контекст функции, если она запускается, единственный способ остановить ее продолжение - это явно return.

Если вы хотите убедиться, что остальныефункция перестает работать при вызове preventDefault(), меняется на:

  if (event.cancelable) {
    event.preventDefault();
    return;
  }

Также было бы неплохо определить event в качестве аргумента, который принимает обработчик, вместо того, чтобы полагаться на неявно глобальныйwindow.event (что, хотя работает в некоторых браузерах, не очень хорошая идея для использования ).

var btn = document.getElementById('btn')
var wrap = document.getElementById('wrap')

btn.addEventListener('click', function(event) {
  event.stopPropagation()
  if (event.cancelable) {
    event.preventDefault();
    return;
  }
  alert('Alert on btn is triggered')
})


function alerted() {
  alert('Alerted fired')
}

wrap.addEventListener('click', function() {
  alert(this.id)
  alert(event.target.tagName + "#" + event.target.id)
})
#wrap {
  padding: 20px;
  border: 1px solid red;
}
<div id="wrap" onclick="alerted">
  <button id="btn" onclick="alerted">Click Me</button>
</div>
1 голос
/ 22 сентября 2019

Объяснение: предупреждение не является событием по умолчанию в вашем событии щелчка, вызов event.preventDefault(); или не будет активировать предупреждение в любом случае.

preventDefault() зависит от события по умолчанию.Пример: использование preventDefault() при событии нажатия предотвратит нажатие триггера или использование preventDefault() при нажатии клавиши не даст событие нажатия клавиши по умолчанию.

Как и текущий ответ, для предотвращения предупреждения используйте return;

Кроме того, я только что заметил, ваш код onclick="alerted" должен быть onclick="alerted()"

ОБНОВЛЕНИЕ:

Объяснение 1: Предупреждение не будетогонь в btn, потому что это было предотвращено.вы поставили alerted() на onclick, а событие click было предотвращено.Другими словами, оповещение находится внутри щелчка, щелчок был предотвращен, поэтому оповещение не сработает.

Объяснение 2: Кнопка - это объект, а не событие, объекты могут иметь одинаковые события.Пример: div являются контейнером, но вы можете использовать событие click для них.

0 голосов
/ 22 сентября 2019

Потому что, когда событие срабатывает, даже если вы остановите его распространение, оно не будет срабатывать в других прослушивателях событий, но ваша функция продолжит выполняться.

...