Stimulus — это легковесный JavaScript-фреймворк, ориентированный на добавление интерактивности к HTML без необходимости переписывать всю архитектуру приложения. Одной из ключевых концепций Stimulus являются таргеты. Они позволяют легко взаимодействовать с конкретными элементами DOM, обеспечивая читаемый и поддерживаемый код.
Таргет в Stimulus — это элемент DOM, который обозначен с помощью
специального атрибута data-<controller>-target.
Контроллер может затем ссылаться на эти элементы напрямую, не прибегая к
стандартным методам поиска через querySelector.
Пример определения таргета:
<div data-controller="example">
<input data-example-target="input" type="text">
<button data-action="click->example#submit">Отправить</button>
</div>
В контроллере example можно обратиться к таргету
так:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["input"]
submit() {
console.log(this.inputTarget.value);
}
}
Ключевые моменты:
static targets — массив имен таргетов.data-<controller>-target автоматически создаёт
свойство <name>Target в контроллере.<name>Targets для получения
коллекции.Stimulus позволяет иметь несколько элементов с одинаковым именем таргета. Это полезно для группировки элементов, например, списка кнопок или полей формы.
<div data-controller="tabs">
<button data-tabs-target="tab">Вкладка 1</button>
<button data-tabs-target="tab">Вкладка 2</button>
<button data-tabs-target="tab">Вкладка 3</button>
</div>
В контроллере можно работать со всеми таргетами сразу:
export default class extends Controller {
static targets = ["tab"]
highlight(index) {
this.tabTargets.forEach((tab, i) => {
tab.classList.toggle("active", i === index);
});
}
}
Особенности:
this.tabTargets возвращает массив элементов.Target и Targets различаются по
числу элементов: одиночный или коллекция.Статические таргеты определяются в HTML на этапе рендеринга страницы. Динамические таргеты позволяют работать с элементами, которые создаются или удаляются в процессе работы приложения.
Stimulus автоматически обновляет коллекцию таргетов при изменении
DOM, если элементы создаются через innerHTML или другие
методы, поддерживающие MutationObserver.
Пример динамического добавления:
<div data-controller="list">
<button data-action="click->list#addItem">Добавить элемент</button>
<ul data-list-target="items"></ul>
</div>
export default class extends Controller {
static targets = ["items"]
addItem() {
const li = document.createElement("li");
li.textContent = "Новый элемент";
li.dataset.listTarget = "items";
this.itemsTarget.appendChild(li);
}
}
Особенности динамических таргетов:
Stimulus предоставляет несколько удобных методов для работы с таргетами:
this.<targetName>Target — доступ к одиночному
элементу.this.<targetName>Targets — коллекция
элементов.this.has<TargetName>Target — проверка наличия
хотя бы одного элемента.this.<targetName>Target и
this.<targetName>Targets всегда актуальны, даже при
динамическом добавлении элементов.Пример проверки существования таргета:
if (this.hasInputTarget) {
this.inputTarget.focus();
}
button, form,
modalContent.querySelector.Targets
удобно для циклических операций или группировки элементов с одинаковой
функциональностью.Таргеты тесно интегрированы с механизмом действий
(data-action). Это позволяет легко привязывать события к
конкретным элементам и манипулировать ими через контроллер:
<div data-controller="counter">
<button data-counter-target="increment" data-action="click->counter#increase">+</button>
<span data-counter-target="value">0</span>
</div>
export default class extends Controller {
static targets = ["value"]
increase() {
this.valueTarget.textContent = parseInt(this.valueTarget.textContent) + 1;
}
}
Каждый таргет получает свою функцию без необходимости вручную искать элементы.
Часто встречается сценарий, когда часть элементов статична, а часть создаётся динамически. Stimulus позволяет без проблем комбинировать оба подхода, сохраняя единообразный интерфейс к таргетам.
<div data-controller="gallery">
<div data-gallery-target="container">
<img src="img1.jpg" data-gallery-target="photo">
<img src="img2.jpg" data-gallery-target="photo">
</div>
<button data-action="click->gallery#addPhoto">Добавить фото</button>
</div>
export default class extends Controller {
static targets = ["container", "photo"]
addPhoto() {
const img = document.createElement("img");
img.src = "new.jpg";
img.dataset.galleryTarget = "photo";
this.containerTarget.appendChild(img);
}
}
Все новые элементы автоматически становятся частью
photoTargets, позволяя работать с ними так же, как с
первоначальными.
Использование статических и динамических таргетов делает код Stimulus структурированным, минимизирует прямое взаимодействие с DOM и упрощает поддержку сложной интерактивной логики. Комбинирование таргетов с действиями позволяет создавать высоко модульные и читаемые контроллеры, адаптированные к динамическому изменению интерфейса.