PreventDefault игнорируется для CustomEvent

andreymal

На MDN в документации dispatchEvent написано:

The return value is <code>false</code> if at least one of the event handlers which handled this event called <code>Event.preventDefault()</code>. Otherwise it returns <code>true</code>.

Ну, я и пишу:

var btn = document.getElementById('btn');
btn.onclick = function() {
    var event = new CustomEvent('customevent');
    var defaultPrevented = !btn.dispatchEvent(event);
    console.log(
        defaultPrevented ? 'preventDefault вызвали' : 'preventDefault НЕ вызвали!'
    );
};

btn.addEventListener('customevent', function(event) {
    event.preventDefault();
    console.log('Кастомное событие!');
    return false;
});
<button id="btn">Click me</button>

Но мой Firefox (впрочем, и Chromium тоже) продолжает упорно писать «preventDefault НЕ вызвали!», хотя я его вполне вызываю.

(Если я его не вызываю, то тоже пишет «preventDefault НЕ вызвали!», если что.)

Что я делаю не так?

Я уже кучу кода написал с расчётом на то, что это будет работать :(

1 ответ

andreymal

Как указано в спецификации

The preventDefault() method, when invoked, must set the canceled flag <em>if the <span>cancelable attribute</span> value is true</em> and the in passive listener flag is unset.

То есть, данный метод устанавливает canceled флаг, если событие cancelable.

По умолчанию, значение атрибута cancelable у события - false, поэтому вызов preventDefault не оказывает никакого влияния на поведение.

Для установки cancelable нужно воспользоваться вторым параметром в конструкторе CustomEvent

Например:

var btn = document.getElementById('btn');
btn.onclick = function() {
  var e = new CustomEvent('customevent', {
    cancelable: true
  });
  var defaultPrevented = !btn.dispatchEvent(e);
  console.log(
    defaultPrevented ? 'preventDefault вызвали' : 'preventDefault НЕ вызвали!'
  );
};

btn.addEventListener('customevent', function(event) {
  event.preventDefault();
  console.log('Кастомное событие!');
  return false;
});
<button id="btn">Click me</button>

licensed under cc by-sa 3.0 with attribution.