Хочешь проверить свои знания по фронтенду?
Подпишись на наш канал с тестами по HTML/CSS/JS в Telegram!
×
Браузеры имеют установленные по умолчанию варианты поведения в различных случаях.
Например, когда пользователь нажимает кнопку «Отправить», по умолчанию форма отправляется к указанному обработчику.
А при клике по потомку элемента событие клика также затрагивает сам элемент, потому что это главный контейнер.
В некоторых случаях вам может понадобиться перекрыть эти установки по умолчанию. В этой статье мы познакомимся с методами event.preventDefault() и event.stopPropagation(). С их помощью мы будем отменять некоторые дефолтные действия браузера.
event.preventDefault()
Этот метод предотвращает дефолтные действия, предпринимаемые браузером при запуске события.
Давайте рассмотрим несколько примеров таких действий, установленных по умолчанию, и способы их предотвращения при помощи event.preventDefault().
Как отменить дефолтную отправку формы
Когда пользователь отправляет форму (нажимает кнопку «Отправить»), действие по умолчанию для формы — отправка данных на URL, где данные будут обработаны.
Элементы формы имеют атрибуты action и method, которые указывают URL, по которому отсылаются данные, и тип запроса (get, post и т. п.).
Если эти атрибуты не переданы, по умолчанию в качестве URL будет использоваться текущий URL, по которому была отправлена форма. В качестве метода по умолчанию используется get.
Например, этот код:
<form> <input name="email" /> <input name="password" /> <input type="submit" /> </form>
даст такой результат:
При отправке формы с входными данными «dillion» и «password» вы увидите, что запрос get отправлен по адресу 127.0.0.1:5500/index.html:
Так браузеры обрабатывают формы по умолчанию.
Но с данными можно много всего сделать до отсылки запроса. Современный подход к работе с формами вообще предполагает такие дополнительные действия.
Прежде чем отправить данные по указанному адресу вы можете выполнить валидацию данных, различные проверки, обработку, настройку заголовков.
Если вы хотите сделать что-либо подобное, вам нужно отменить отправку, выполняемую по умолчанию.
Делается это так:
<form id='form'> ... </form>
const form=document.getElementById('form') form.addEventListener('submit', (event)=> { event.preventDefault() // process data and submit a request manually })
Теперь отправка формы в ваших руках.
От редакции Techrocks. Предлагаем также почитать другие статьи о создании форм:
Как отменить действие по умолчанию для клика по ссылке
Когда вы кликаете по ссылке (тег a с атрибутом href), действие по умолчанию — переход по этой ссылке.
Но что, если вы хотите сделать что-то перед переходом? Например, проверить, есть ли доступ у пользователя к той странице, на которую он хочет перейти. Вот как это сделать:
<a href="https://google.com">Google</a>
const link=document.getElementById("link") link.addEventListener("click", event=> { event.preventDefault() // сделать что-то и перейти })
Теперь при клике на ссылку «Google» переход по ссылке не происходит автоматически. Вы отменили действие перехода, установленное по умолчанию, и вам придется управлять им самостоятельно.
event.stopPropagation()
Propagation — это распространение событий. Метод stopPropagation используется для предотвращения распространения (всплытия) событий, когда событие запускается на отдельном элементе.
В JavaScript, когда событие запускается на одном элементе, оно всплывает вверх по дереву родительских элементов. Если элемент с событием находится внутри родительского контейнера, родитель тоже получает это событие.
Чтобы в этом разобраться, используем пример.
Клик на потомке элемента
Допустим, у вас есть следующие элементы:
<div> <button>Click me</button> </div>
Когда вы кликаете на button, вы также кликаете по контейнеру div, потому что button находится в этом контейнере. Эта логика означает, что событие клика всплывает от кнопки к контейнеру. На этом событие не останавливается, оно продолжает всплывать к более далеким предкам, пока не достигнет корня.
Чтобы это проверить, рассмотрим код:
<div > <button >Click me</button> </div>
const div=document.getElementById('div') const button=document.getElementById('button') button.addEventListener('click', ()=> { console.log('button clicked') }) div.addEventListener('click', ()=> { console.log('div container clicked') })
Если вы запустите этот код в браузере и нажмете на кнопку, вы получите следующий результат:
Контейнер div тоже получает событие click.
Всплытие событий — поведение браузера по умолчанию. Но в некоторых случаях вам может потребоваться другое поведение.
Рассмотрим пример.
Вот всплывающее окно нового сообщения в Gmail:
Вверху у вас три кнопки для различных действий. Одна сворачивает окно, вторая раскрывает его на весь экран, а третья закрывает.
Но верхняя панель с текстом «New Message» тоже имеет обработчик событий. Если по ней кликнуть, окно сворачивается:
Кликая на любую из кнопок, вы не хотите, чтобы событие клика распространялось на верхнюю панель и при этом выполнялась функция для этого события. То есть, кликая на кнопку «Закрыть», вы не хотите, чтобы верхняя панель сворачивалась.
В подобных случаях вам нужно остановить всплытие события.
Предположим, наше всплывающее окно построено следующим образом:
<div id='top-bar'> <!-- The Message Element --> <!-- The Buttons --> </div>
const topBar=document.getElementById('top-bar') const closeButton=document.getElementById('close-btn') topBar.addEventListener('click', ()=> { // minimize or maximize popup }) closeButton.addEventListener('click', ()=> { // close popup })
Чтобы предотвратить всплытие события к верхней панели, вам нужно добавить метод stopPropagation для слушателя событий button. Выглядит это так:
closeButton.addEventListener('click', (event)=> { event.stopPropagation() // close popup })
Таким образом верхняя панель будет получать событие click, только если кликнут непосредственно по ней.
От редакции Techrocks. Возможно, вас также заинтересует статья «Как создать ссылку mailto в HTML».
Итоги
Мы познакомились с методами event.preventDefault() и event.stopPropagation(). Первый предотвращает действия браузера, установленные по умолчанию, а второй — дефолтное поведение событий — распространение вверх по дереву.
Эти действия и поведение, установленные по умолчанию, не являются ошибками, вам не обязательно что-то с ними делать. Но бывают случаи, когда разработчику нужно их отменить. Некоторые из таких случаев мы рассмотрели в этой статье.
Перевод статьи «How to Manage Browser Defaults with event.preventDefault() and event.stopPropagation()».
Запись Методы event.preventDefault() и event.stopPropagation() впервые появилась Techrocks.