frontend logo

Хочешь проверить свои знания по фронтенду?

Подпишись на наш канал с тестами по HTML/CSS/JS в Telegram!

Решать задачи

×

Методы event.preventDefault() и event.stopPropagation()

Браузеры имеют установленные по умолчанию варианты поведения в различных случаях.

Например, когда пользователь нажимает кнопку «Отправить», по умолчанию форма отправляется к указанному обработчику.

А при клике по потомку элемента событие клика также затрагивает сам элемент, потому что это главный контейнер.

В некоторых случаях вам может понадобиться перекрыть эти установки по умолчанию. В этой статье мы познакомимся с методами 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>

даст такой результат:

Методы event.preventDefault() и event.stopPropagation()

При отправке формы с входными данными «dillion» и «password» вы увидите, что запрос get отправлен по адресу 127.0.0.1:5500/index.html:

Методы event.preventDefault() и event.stopPropagation()

Так браузеры обрабатывают формы по умолчанию.

Но с данными можно много всего сделать до отсылки запроса. Современный подход к работе с формами вообще предполагает такие дополнительные действия.

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

Если вы хотите сделать что-либо подобное, вам нужно отменить отправку, выполняемую по умолчанию.

Делается это так:

<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 id="link" 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 id="div">
  <button id="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')
})

Если вы запустите этот код в браузере и нажмете на кнопку, вы получите следующий результат:

Методы event.preventDefault() и event.stopPropagation()

Контейнер div тоже получает событие click.

Всплытие событий — поведение браузера по умолчанию. Но в некоторых случаях вам может потребоваться другое поведение.

Рассмотрим пример.

Вот всплывающее окно нового сообщения в Gmail:

Методы event.preventDefault() и event.stopPropagation()

Вверху у вас три кнопки для различных действий. Одна сворачивает окно, вторая раскрывает его на весь экран, а третья закрывает.

Но верхняя панель с текстом «New Message» тоже имеет обработчик событий. Если по ней кликнуть, окно сворачивается:

Методы event.preventDefault() и event.stopPropagation()

Кликая на любую из кнопок, вы не хотите, чтобы событие клика распространялось на верхнюю панель и при этом выполнялась функция для этого события. То есть, кликая на кнопку «Закрыть», вы не хотите, чтобы верхняя панель сворачивалась.

В подобных случаях вам нужно остановить всплытие события.

Предположим, наше всплывающее окно построено следующим образом:

<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.

Похожие записи

AEGIS Algorithms Android Angular Apache Airflow Apache Druid Apache Flink Apache Spark API API Canvas AppSec Architecture Artificial Intelligence Astro Authentication Authorization AutoGPT AWS AWS Aurora AWS Boto3 AWS EC2 AWS Lambda Azure Babylon.js Backend bash Beautiful Soup Bento UI Big Data Binary Tree Browser API Bun Career Cassandra Charts ChatGPT Chrome Extension Clean Code CLI ClickHouse Coding Codux Combine Compose Computer Context Fusion Copilot Cosmo Route CProgramming cron Cryptography CSS CTF Cypress DALL-E Data Analysis Data science Database dbt dbt Cloud deno Design Design Patterns Detekt Development Distributed Systems Django Docker Docker Hub Drizzle DRY DuckDB Express FastAPI Flask Flutter For Beginners Front End Development Game Development GCN GCP Geospatial Git GitHub Actions GitHub Pages Gitlab GMS GoFr Golang Google Google Sheets Google Wire GPT-3 GPT3 Gradio Gradle Grafana Graphic Design GraphQL gRPC Guidance HMS Hotwire HTML Huawei HuggingFace IndexedDB InfoSec Interview iOS Jackknife Java JavaScript Jetpack Compose JSON Kafka Kotlin Kubernetes LangChain Laravel Linux LlaMA LLM localStorage Logging Machine Learning Magento Math Mermaid Micro Frontends Mobile Mobile App Development mondayDB MongoDB Mongoose MySQL Naming NestJS NET NetMock Networks NextJS NLP Node.js Nodejs NoSQL NPM OOP OpenAI OTP Pandas PDF PHP Playwright Plotly Polars PostgreSQL Prefect Productivity Programming Prometheus Puppeteer Pushover Python Pytorch Quarkus Rabbitmq RAG Ramda Raspberry Pi React React Native Reactor Redis REST API Revolut Riverpod RProgramming Ruby Ruby on Rails Rust Scalene SCDB ScyllaDB Selenium Servers Sklearn SLO SnowFlake Snowkase Software Architecture Software Development Solara Solid Spring Boot SQL SQLite Streamlit SudoLang Supabase Swift SwiftUI Tailwind CSS Taipy Terraform Testing Transformers TURN TypeScript Ubuntu UI Design Unix UX UX Design Vim Vite VSCode Vue Web Architecture Web Components Web Development Web Frameworks Web Scraping Web-разработка Webassembly Websocket Whisper Widgets WordPress YAML YouTube Наука о данных Разное Тренды

Go — единственный выбор для бэкенд-разработчика?

Вы пропустили

AEGIS Algorithms Android Angular Apache Airflow Apache Druid Apache Flink Apache Spark API API Canvas AppSec Architecture Artificial Intelligence Astro Authentication Authorization AutoGPT AWS AWS Aurora AWS Boto3 AWS EC2 AWS Lambda Azure Babylon.js Backend bash Beautiful Soup Bento UI Big Data Binary Tree Browser API Bun Career Cassandra Charts ChatGPT Chrome Extension Clean Code CLI ClickHouse Coding Codux Combine Compose Computer Context Fusion Copilot Cosmo Route CProgramming cron Cryptography CSS CTF Cypress DALL-E Data Analysis Data science Database dbt dbt Cloud deno Design Design Patterns Detekt Development Distributed Systems Django Docker Docker Hub Drizzle DRY DuckDB Express FastAPI Flask Flutter For Beginners Front End Development Game Development GCN GCP Geospatial Git GitHub Actions GitHub Pages Gitlab GMS GoFr Golang Google Google Sheets Google Wire GPT-3 GPT3 Gradio Gradle Grafana Graphic Design GraphQL gRPC Guidance HMS Hotwire HTML Huawei HuggingFace IndexedDB InfoSec Interview iOS Jackknife Java JavaScript Jetpack Compose JSON Kafka Kotlin Kubernetes LangChain Laravel Linux LlaMA LLM localStorage Logging Machine Learning Magento Math Mermaid Micro Frontends Mobile Mobile App Development mondayDB MongoDB Mongoose MySQL Naming NestJS NET NetMock Networks NextJS NLP Node.js Nodejs NoSQL NPM OOP OpenAI OTP Pandas PDF PHP Playwright Plotly Polars PostgreSQL Prefect Productivity Programming Prometheus Puppeteer Pushover Python Pytorch Quarkus Rabbitmq RAG Ramda Raspberry Pi React React Native Reactor Redis REST API Revolut Riverpod RProgramming Ruby Ruby on Rails Rust Scalene SCDB ScyllaDB Selenium Servers Sklearn SLO SnowFlake Snowkase Software Architecture Software Development Solara Solid Spring Boot SQL SQLite Streamlit SudoLang Supabase Swift SwiftUI Tailwind CSS Taipy Terraform Testing Transformers TURN TypeScript Ubuntu UI Design Unix UX UX Design Vim Vite VSCode Vue Web Architecture Web Components Web Development Web Frameworks Web Scraping Web-разработка Webassembly Websocket Whisper Widgets WordPress YAML YouTube Наука о данных Разное Тренды

Go — единственный выбор для бэкенд-разработчика?

AEGIS Algorithms Android Angular Apache Airflow Apache Druid Apache Flink Apache Spark API API Canvas AppSec Architecture Artificial Intelligence Astro Authentication Authorization AutoGPT AWS AWS Aurora AWS Boto3 AWS EC2 AWS Lambda Azure Babylon.js Backend bash Beautiful Soup Bento UI Big Data Binary Tree Browser API Bun Career Cassandra Charts ChatGPT Chrome Extension Clean Code CLI ClickHouse Coding Codux Combine Compose Computer Context Fusion Copilot Cosmo Route CProgramming cron Cryptography CSS CTF Cypress DALL-E Data Analysis Data science Database dbt dbt Cloud deno Design Design Patterns Detekt Development Distributed Systems Django Docker Docker Hub Drizzle DRY DuckDB Express FastAPI Flask Flutter For Beginners Front End Development Game Development GCN GCP Geospatial Git GitHub Actions GitHub Pages Gitlab GMS GoFr Golang Google Google Sheets Google Wire GPT-3 GPT3 Gradio Gradle Grafana Graphic Design GraphQL gRPC Guidance HMS Hotwire HTML Huawei HuggingFace IndexedDB InfoSec Interview iOS Jackknife Java JavaScript Jetpack Compose JSON Kafka Kotlin Kubernetes LangChain Laravel Linux LlaMA LLM localStorage Logging Machine Learning Magento Math Mermaid Micro Frontends Mobile Mobile App Development mondayDB MongoDB Mongoose MySQL Naming NestJS NET NetMock Networks NextJS NLP Node.js Nodejs NoSQL NPM OOP OpenAI OTP Pandas PDF PHP Playwright Plotly Polars PostgreSQL Prefect Productivity Programming Prometheus Puppeteer Pushover Python Pytorch Quarkus Rabbitmq RAG Ramda Raspberry Pi React React Native Reactor Redis REST API Revolut Riverpod RProgramming Ruby Ruby on Rails Rust Scalene SCDB ScyllaDB Selenium Servers Sklearn SLO SnowFlake Snowkase Software Architecture Software Development Solara Solid Spring Boot SQL SQLite Streamlit SudoLang Supabase Swift SwiftUI Tailwind CSS Taipy Terraform Testing Transformers TURN TypeScript Ubuntu UI Design Unix UX UX Design Vim Vite VSCode Vue Web Architecture Web Components Web Development Web Frameworks Web Scraping Web-разработка Webassembly Websocket Whisper Widgets WordPress YAML YouTube Наука о данных Разное Тренды

Производительность в Jetpack Compose: стабильность и неизменяемость