Avatar ·

event.preventDefault() против return false в обработчиках событий JavaScript

Привет всем! Я начал изучать JavaScript и jQuery, и столкнулся с непонятной ситуацией. Когда я хочу отменить стандартное действие браузера (например, переход по ссылке или отправку формы), я вижу два способа: можно вызвать `event.preventDefault()`, а можно просто написать `return false` в конце обработчика. Например, у меня есть такая форма: ```html
``` Я пишу обработчик: ```javascript document.getElementById('myForm').addEventListener('submit', function(event) { // проверка данных... event.preventDefault(); }); ``` Но в jQuery я часто вижу такой код: ```javascript $('#myForm').on('submit', function() { // проверка данных... return false; }); ``` Вроде бы оба делают одно и то же — форма не отправляется. Но я заметил, что если я использую `return false` в чистом JavaScript (без jQuery), то это не работает. А в jQuery работает. Так в чем же разница? Когда нужно использовать `event.preventDefault()`, а когда `return false`? И почему `return false` не работает в addEventListener? Буду благодарен за подробное объяснение с примерами. <<>>

Основное различие: отмена действия vs. остановка распространения

Главное, что нужно запомнить: event.preventDefault() и return false — это не одно и то же. Они решают разные задачи, хотя в некоторых случаях (особенно в jQuery) их эффект может казаться одинаковым.

1. event.preventDefault() — отмена стандартного поведения

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

Какие действия можно отменить:

  • Переход по ссылке (<a href="...">)
  • Отправку формы (<input type="submit">)
  • Открытие контекстного меню (contextmenu)
  • Выделение текста (selectstart)
  • Перетаскивание (dragstart)

Пример с чистой ссылкой:

document.querySelector('a').addEventListener('click', function(event) {
  event.preventDefault(); // ссылка не откроется
  console.log('Клик обработан');
  // Другие обработчики на этом же элементе или родителях сработают!
});

2. return false — два разных поведения

Тут есть важный нюанс: return false работает по-разному в зависимости от того, как вы назначили обработчик.

В jQuery (и в старом атрибуте onclick="return false"):

// jQuery
$('a').on('click', function() {
  console.log('Клик');
  return false; // = event.preventDefault() + event.stopPropagation()
});

// Атрибут HTML
<a href="#" onclick="return false;">Ссылка</a>

В jQuery return false делает сразу две вещи:

  • Вызывает event.preventDefault() — отменяет стандартное действие
  • Вызывает event.stopPropagation() — останавливает всплытие события

В чистом JavaScript (addEventListener):

// Чистый JS — return false НЕ РАБОТАЕТ!
document.querySelector('a').addEventListener('click', function(event) {
  console.log('Клик');
  return false; // Просто возвращает значение, но НЕ отменяет действие!
  // Ссылка всё равно откроется
});

Для addEventListener возвращаемое значение игнорируется. Нужно явно вызывать event.preventDefault().

3. Когда что использовать?

Используйте event.preventDefault(), если:

  • Работаете с чистым JavaScript (addEventListener)
  • Нужно отменить только стандартное действие, но разрешить всплытие события (например, для делегирования)
  • Хотите явно указать намерение в коде

Используйте return false в jQuery, если:

  • Работаете с jQuery (это идиоматично)
  • Хотите и отменить действие, и остановить всплытие (но будьте осторожны — это может сломать делегирование)

Пример, где разница критична:

// Делегирование — обработчик на родителе
document.querySelector('div').addEventListener('click', function(event) {
  if (event.target.tagName === 'A') {
    event.preventDefault(); // Отменяем переход по ссылке
    // НО событие всё равно всплывёт к родителю
  }
});

// Если бы мы использовали return false в jQuery,
// событие бы не всплыло, и делегирование бы не сработало

4. Практический совет

В современном JavaScript (без jQuery) всегда используйте event.preventDefault(). Это явно, предсказуемо и соответствует стандартам. return false оставьте для jQuery или устаревших атрибутов HTML.

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

<<>>

Дополнение: event.stopPropagation() и event.stopImmediatePropagation()

Коллега выше отлично объяснил базовую разницу. Хочу добавить пару важных моментов для полного понимания.

1. Три разных метода для трёх разных задач

Вот полная картина того, что можно сделать с событием:

  • event.preventDefault() — отменяет стандартное действие браузера
  • event.stopPropagation() — останавливает всплытие события к родительским элементам
  • event.stopImmediatePropagation() — останавливает всплытие И не даёт сработать другим обработчикам на том же элементе

Пример с stopImmediatePropagation:

element.addEventListener('click', function(event) {
  event.stopImmediatePropagation();
  console.log('Первый обработчик');
});

// Этот обработчик НЕ сработает
element.addEventListener('click', function(event) {
  console.log('Второй обработчик'); // Никогда не вызовется
});

2. return false в jQuery — это "всё в одном"

Когда вы пишете return false в jQuery, он внутри делает:

// jQuery source (упрощённо)
function handler(event) {
  if (ret === false) {
    event.preventDefault();
    event.stopPropagation();
  }
}

Поэтому в jQuery return false — это удобный сокращённый синтаксис для двух операций. Но если вам нужно только отменить действие, а всплытие оставить (например, для делегирования), лучше использовать event.preventDefault() даже в jQuery.

3. Проверка: можно ли отменить действие?

Не все события можно отменить. Проверить это можно через свойство event.cancelable:

element.addEventListener('click', function(event) {
  if (event.cancelable) {
    event.preventDefault();
  } else {
    console.log('Это событие нельзя отменить');
  }
});

Например, событие mouseenter или scroll (в некоторых браузерах) нельзя отменить через preventDefault().

Вывод: запомните три инструмента: preventDefault для отмены действия, stopPropagation для остановки всплытия, stopImmediatePropagation для полной блокировки. И используйте их явно — это сделает ваш код надёжнее и понятнее.