Stimulus предоставляет мощный и лаконичный способ управления поведением элементов DOM, и понимание механизма событий является ключевым для создания интерактивных интерфейсов. Два фундаментальных инструмента — предотвращение всплытия событий (event bubbling) и отмена действий по умолчанию (preventDefault) — позволяют полностью контролировать реакцию элементов на пользовательские действия.
В стандартном JavaScript любое событие, происходящее на вложенном
элементе, начинает всплывать к родительским элементам.
Это значит, что один клик по кнопке может вызвать обработчики на самой
кнопке и на всех родительских контейнерах. В Stimulus этот процесс можно
контролировать с помощью модификатора
@stop.
<div data-controller="menu">
<button data-action="click->menu#open click@stop">Открыть меню</button>
</div>
В примере выше обработчик menu#open будет вызван только
для самой кнопки, а событие не будет всплывать к
контейнеру div. Модификатор @stop
автоматически вызывает event.stopPropagation(), устраняя
необходимость писать дополнительный код в контроллере.
Особенности использования @stop:
click, submit,
mouseover.@prevent.Некоторые действия браузера происходят автоматически, например:
<a href="#">)<form> с кнопкой
submit)contextmenu)Чтобы предотвратить стандартное поведение браузера, используется
модификатор @prevent.
<form data-controller="form" data-action="submit->form#send submit@prevent">
<input type="text" name="username">
<button type="submit">Отправить</button>
</form>
При такой конфигурации метод form#send вызывается, но
стандартная отправка формы не выполняется, что
позволяет обрабатывать данные через AJAX или проводить кастомную
валидацию.
Ключевые моменты работы @prevent:
event.preventDefault().@stop для полного контроля
события.@prevent и
@stopЧасто необходимо одновременно отменить стандартное действие и остановить всплытие:
<a href="/delete" data-controller="link" data-action="click->link#delete click@prevent@stop">
Удалить элемент
</a>
В этом случае:
/delete.Такое сочетание особенно полезно для динамических интерфейсов, где одни и те же события могут обрабатываться разными слоями DOM.
Помимо использования модификаторов в HTML, можно контролировать события программно в контроллере Stimulus:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
this.element.addEventListener("click", this.handleClick)
}
handleClick(event) {
event.preventDefault() // отмена стандартного действия
event.stopPropagation() // остановка всплытия
console.log("Событие обработано локально")
}
}
Такой подход полезен при необходимости более сложной логики, когда
модификаторы @prevent и @stop
недостаточны.
@prevent и
@stop при создании интерактивных элементов, таких
как кнопки удаления, ссылки с кастомной навигацией или выпадающие
меню.touchstart и
click).Если один элемент управляется несколькими контроллерами, предотвращение всплытия помогает изолировать их действия:
<div data-controller="parent">
<button data-controller="child" data-action="click->child#doSomething click@stop">Нажать</button>
</div>
В данном примере событие кнопки не достигнет родительского контроллера, позволяя дочернему полностью контролировать свою логику.
Модификаторы работают для всех стандартных событий DOM:
click, dblclicksubmit, change, inputkeydown, keyupcontextmenu и другиеЭто позволяет создавать универсальные контроллеры с минимальным количеством кода.
Остановка всплытия при клике на кнопку внутри модального окна:
<div data-controller="modal" data-action="click->modal#close">
<div data-action="click@stop">
<button data-action="click->modal#save">Сохранить</button>
</div>
</div>
Отмена отправки формы при валидации:
<form data-controller="signup" data-action="submit->signup#validate submit@prevent">
<input type="email" name="email">
<button type="submit">Регистрация</button>
</form>
Эти приёмы являются основой управления событиями в Stimulus и позволяют создавать чистую, предсказуемую и управляемую реакцию интерфейса на действия пользователя.