Действия браузера по умолчанию
Браузеры выполняют определённые действия по умолчанию в ответ на пользовательские взаимодействия: переход по ссылке, отправка формы и другие.
Понимание действий браузера по умолчанию и управление ими в JavaScript
В веб-разработке браузеры выполняют определённые действия по умолчанию в ответ на взаимодействия пользователя. Клик по ссылке открывает новую страницу, отправка формы передаёт данные на сервер, а правый клик показывает контекстное меню — всё это происходит без какого-либо JavaScript. JavaScript позволяет перехватывать эти встроенные поведения, чтобы заменить, дополнить или отменить их.
В этой главе рассматривается, что такое действия по умолчанию, как отменить их с помощью event.preventDefault(), чем отличается отмена действия по умолчанию от остановки распространения, как проверить, было ли действие уже отменено, а также типичные ловушки (пассивные обработчики, неотменяемые события и устаревший шаблон return false). Если события для вас — новая тема, начните с главы Введение в события браузера.
Что такое действия браузера по умолчанию?
Действие по умолчанию — это поведение, которое браузер выполняет автоматически при возникновении события, без каких-либо обработчиков с вашей стороны. Распространённые примеры:
- Переход по URL при клике на ссылку
<a>. - Отправка формы (и перезагрузка страницы) при нажатии кнопки submit.
- Отображение нативного контекстного меню при правом клике (
contextmenu). - Прокрутка страницы при нажатии пробела или клавиш со стрелками.
- Выделение текста при
mousedownи его перетаскивание приdragstart. - Установка флажка или переход по метке при клике на неё.
Многие обработчики выполняются до действия по умолчанию: сначала браузер вызывает ваш обработчик click/submit/keydown, а затем выполняет встроенное поведение. Именно такой порядок делает возможной отмену действия по умолчанию внутри обработчика.
Предотвращение действий по умолчанию
Чтобы остановить встроенное поведение браузера, вызовите event.preventDefault() внутри обработчика. После вызова браузер пропускает встроенное действие для данного события — но ваш обработчик всё равно выполняется до конца, а событие продолжает распространяться (всплывать), если только вы не остановите его отдельно.
Примечание: Не путайте preventDefault() с stopPropagation(). preventDefault() отменяет действие по умолчанию (переход, отправку, прокрутку). stopPropagation() останавливает распространение события к родительским элементам — см. Всплытие и погружение. Это независимые механизмы: отмена действия по умолчанию не останавливает всплытие, а остановка всплытия не отменяет действие по умолчанию.
Пример на JavaScript: предотвращение открытия ссылки
<a href="https://www.example.com" id="myLink">Go to Example.com</a>
<script>
document.getElementById('myLink').addEventListener('click', function(event) {
event.preventDefault(); // Stops the default link behavior
alert('Default action prevented! Link will not open.');
});
</script>Пояснение:
- Обработчик события: Привязывает обработчик события
clickк ссылке. - Предотвращение действия по умолчанию: Метод
preventDefault()вызывается на объекте события, останавливая переход браузера по URL, указанному в атрибутеhref.
Более сложный пример: обработка отправки формы
Рассмотрим форму, в которой нужно проверить введённые данные перед отправкой. Если валидация не прошла, отправка формы предотвращается. Подробнее о событии submit см. в главе Формы: событие и метод submit.
<form id="myForm">
Enter your name: <input type="text" name="username" required>
<input type="submit" value="Submit">
</form>
<div id="formFeedback"></div>
<script>
document.getElementById('myForm').addEventListener('submit', function(event) {
var input = this.elements.username.value;
if (input.length < 4) {
event.preventDefault(); // Prevent form from submitting
document.getElementById('formFeedback').textContent = 'Name must be at least 4 characters long.';
} else {
document.getElementById('formFeedback').textContent = 'Form submitted successfully!';
}
});
</script>Пояснение:
- Обработчик события формы: К событию
submitформы привязывается обработчик события. - Валидация: Проверяет, содержит ли имя пользователя не менее 4 символов.
- Обратная связь: Отображает мгновенный отклик на странице. Если валидация не прошла, отправка формы предотвращается.
Пример: пользовательское контекстное меню при правом клике
Веб-приложения могут использовать пользовательские контекстные меню для расширения функциональности. Предотвращая отображение стандартного меню по правому клику, можно показать собственное меню с опциями, актуальными для вашего приложения. (Событие contextmenu вызывается правым кликом — см. Основы событий мыши для смежных событий указателя.)
<div id="contextArea" style="width: 300px; height: 200px; background-color: #f0f0f0; margin-bottom: 10px;">
Right-click on me
</div>
<ul id="customMenu" style="display: none; list-style: none; padding: 10px; background-color: white; border: 1px solid black; position: absolute;">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
<script>
document.getElementById('contextArea').addEventListener('contextmenu', function(event) {
event.preventDefault(); // Prevent the default context menu
var menu = document.getElementById('customMenu');
menu.style.display = 'block';
menu.style.left = event.clientX + 'px';
menu.style.top = event.clientY + 'px';
});
document.addEventListener('click', function(event) {
document.getElementById('customMenu').style.display = 'none';
});
</script>Пояснение:
- Контекстное меню: Событие
contextmenuиспользуется для отображения пользовательского меню, аevent.preventDefault()предотвращает появление стандартного контекстного меню браузера. - Позиционирование: Пользовательское меню позиционируется на основе координат мыши (
event.clientXиevent.clientY). - Глобальный клик: Глобальный обработчик клика скрывает меню при нажатии в любом другом месте страницы.
Проверка того, было ли действие по умолчанию уже отменено
После выполнения обработчика можно прочитать event.defaultPrevented, чтобы узнать, вызвал ли уже какой-либо обработчик preventDefault(). Это полезно, когда несколько обработчиков слушают одно событие, и более поздний не должен действовать, если более ранний уже отменил действие по умолчанию.
const link = document.createElement('a');
link.href = 'https://example.com';
link.addEventListener('click', (event) => {
event.preventDefault();
});
link.addEventListener('click', (event) => {
console.log(event.defaultPrevented); // true
});
// Simulate a click on the link
link.dispatchEvent(new Event('click', { cancelable: true }));Второй обработчик выведет true, поскольку первый уже отменил действие по умолчанию.
Не все события можно отменить
Только отменяемые события имеют действие по умолчанию, которое можно остановить. Перед использованием preventDefault() можно проверить event.cancelable. Такие события, как scroll и DOMContentLoaded, не являются отменяемыми, поэтому вызов preventDefault() для них не имеет эффекта.
const evt = new Event('myevent', { cancelable: true });
console.log(evt.cancelable); // true
evt.preventDefault();
console.log(evt.defaultPrevented); // true
const evt2 = new Event('myevent', { cancelable: false });
evt2.preventDefault();
console.log(evt2.defaultPrevented); // false — could not be preventedПассивные обработчики не могут отменить действие по умолчанию
Для повышения производительности события, связанные с прокруткой (touchstart, touchmove, wheel), можно зарегистрировать как пассивные. Пассивный обработчик обещает не вызывать preventDefault(), что позволяет браузеру выполнять прокрутку, не дожидаясь завершения вашего кода. Если вызвать preventDefault() внутри пассивного обработчика, вызов будет проигнорирован, а в консоль выведется предупреждение.
element.addEventListener('touchmove', (event) => {
// This call is ignored because the listener is passive.
event.preventDefault();
}, { passive: true });Если вам действительно нужно отменить прокрутку, зарегистрируйте обработчик с { passive: false }.
Избегайте устаревшего return false
В старых встроенных обработчиках можно встретить onclick="return false" для отмены действия по умолчанию. Внутри коллбэка addEventListener возврат false не даёт никакого эффекта — там работает только event.preventDefault(). Используйте preventDefault() везде для ясности и единообразия.
<!-- Legacy inline form (works, but discouraged) -->
<a href="https://example.com" onclick="return false">Blocked</a>
<!-- Modern, recommended form -->
<script>
document.querySelector('a').addEventListener('click', (event) => {
event.preventDefault();
});
</script>Заключение
Управление действиями браузера по умолчанию — мощный инструмент в веб-разработке, позволяющий настраивать поведение и обеспечивать расширенный контроль над взаимодействиями пользователя. Будь то предотвращение открытия ссылки, остановка отправки формы или любое другое действие по умолчанию — event.preventDefault() необходим для адаптации пользовательского опыта к конкретным требованиям приложения. Понимание и использование этого метода позволяет разработчикам создавать более интерактивные и удобные веб-приложения.