Классы: динамическое управление CSS-классами

Stimulus предоставляет мощные механизмы для управления поведением HTML-элементов через контроллеры. Одним из наиболее часто используемых инструментов является динамическое управление CSS-классами. Этот подход позволяет изменять визуальное состояние элементов в ответ на события, без необходимости напрямую манипулировать DOM или использовать громоздкие конструкции.

Определение и подключение контроллера

Контроллер в Stimulus создается с помощью класса, который наследует базовый Controller. Для работы с классами используется объект classList элемента, доступного через this.element или через targets.

Пример базовой структуры контроллера:

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["button"];

  connect() {
    console.log("Контроллер подключен");
  }
}

Работа с classList

Методы add, remove, toggle и contains позволяют гибко управлять классами:

  • add – добавляет класс к элементу, если его нет.
  • remove – удаляет класс, если он присутствует.
  • toggle – переключает класс: добавляет, если отсутствует, и удаляет, если есть.
  • contains – проверяет наличие класса.

Пример использования в контроллере:

toggleHighlight() {
  this.element.classList.toggle("highlight");
}

Вызов метода toggleHighlight может быть привязан к событию через data-action:

<div data-controller="highlight" data-action="click->highlight#toggleHighlight">
  Нажми, чтобы изменить состояние
</div>

Использование targets для нескольких элементов

Stimulus позволяет определять targets, чтобы управлять несколькими элементами одновременно:

static targets = ["item"];

highlightAll() {
  this.itemTargets.forEach((element) => {
    element.classList.add("highlight");
  });
}

HTML-разметка:

<div data-controller="highlight">
  <div data-highlight-target="item">Элемент 1</div>
  <div data-highlight-target="item">Элемент 2</div>
  <button data-action="click->highlight#highlightAll">Выделить все</button>
</div>

Динамическое добавление и удаление нескольких классов

Методы add и remove могут принимать несколько аргументов, что позволяет одновременно применять несколько стилей:

applyStyles() {
  this.element.classList.add("bold", "italic", "underline");
}

removeStyles() {
  this.element.classList.remove("bold", "italic", "underline");
}

Управление классами на основе состояния

Часто требуется менять классы в зависимости от внутренних состояний. Для этого удобно использовать свойства контроллера:

static classes = ["active"];

connect() {
  this.active = false;
}

toggleState() {
  this.active = !this.active;
  this.element.classList.toggle(this.activeClass, this.active);
}

HTML-разметка с указанием классов:

<div data-controller="state" data-state-active-class="active" data-action="click->state#toggleState">
  Переключаемый элемент
</div>
  • data-state-active-class указывает, какой класс должен применяться.
  • this.activeClass автоматически связывается с именем, указанным в static classes.

Динамическое управление классами через аргументы и значения

Stimulus позволяет использовать values для динамического определения классов:

static values = { color: String };

applyColor() {
  this.element.classList.add(this.colorValue);
}

HTML:

<div data-controller="color" data-color-color-value="red" data-action="click->color#applyColor">
  Цветной элемент
</div>

При клике элемент получит класс red. Такой подход обеспечивает полную динамичность без необходимости прописывать классы в коде контроллера вручную.

Комплексное состояние с несколькими классами

Для сложных интерфейсов часто нужно управлять несколькими классами в зависимости от состояния. Это можно реализовать через объекты и методы:

static classes = ["open", "closed"];

toggleMenu() {
  const isOpen = this.element.classList.contains(this.openClass);
  this.element.classList.toggle(this.openClass, !isOpen);
  this.element.classList.toggle(this.closedClass, isOpen);
}

HTML-разметка:

<div data-controller="menu" data-menu-open-class="open" data-menu-closed-class="closed" data-action="click->menu#toggleMenu">
  Меню
</div>

Такой подход обеспечивает одновременное управление несколькими классами в зависимости от состояния, делая интерфейс интерактивным и предсказуемым.

Итоговые рекомендации по динамическим классам

  • Использовать targets для групп элементов, чтобы не дублировать код.
  • Применять static classes и values для декларативного управления стилями.
  • Комбинировать методы add, remove и toggle для контроля сложных состояний.
  • Поддерживать читабельность кода, группируя изменения классов в отдельные методы.
  • Для сложных состояний использовать логические флаги внутри контроллера, чтобы не полагаться только на наличие классов в DOM.

Динамическое управление CSS-классами в Stimulus делает интерфейсы легкими для сопровождения, поддерживает реактивность без лишнего JavaScript-кода и позволяет создавать интерактивные элементы с минимальной связью с DOM.