Форум

Методология

Toolbox

Платформа

Сообщество

JavaScript по БЭМ

В БЭМ-методологии JavaScript используется для «оживления» веб-страницы и рассматривается как одна из технологий реализации блока.

В БЭМ к JavaScript применяются дополнительные правила, которые позволяют реализовать все идеи компонентного подхода БЭМ-методологии.

Основные принципы компонентного подхода в JavaScript по БЭМ

JavaScript — это одна из технологий реализации блока, поэтому в работе с JavaScript могут соблюдаться основные идеи БЭМ-методологии:

Единая предметная область

В веб-разработке финальный продукт (например, веб-страница) состоит из разных технологий (HTML, CSS, JS и т.д.). В БЭМ для работы во всех технологиях используются единые термины и подходы к реализации. Таким образом вся команда БЭМ-проекта получает единый язык для общения, то есть работает в терминах блоков, элементов и модификаторов.

Так, JavaScript-реализация блоков не оперирует понятиями DOM-элементов, а использует следующий уровень абстракции — БЭМ-дерево. Это позволяет не опираться на классы, а независимо описывать поведение блоков и их опциональных элементов. Модификаторы в JavaScript используются для выражения логики работы блока или элемента (по аналогии с CSS, где с помощью модификаторов задается внешний вид). Поведение блоков и элементов описывается в JavaScript как набор состояний.

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

Пример

Рассмотрим пример всплывающего окна (popup). Показывать всплывающее окно можно различными способами:

Использование единой предметной области дает возможность на более высоком уровне взаимодействовать с компонентами.

Работа с модификаторами

Модификаторы могут задавать блокам определенные состояния. Логика работы блока реализуется в JavaScript и описывается с помощью состояний. Перевод блока в другое состояние может производиться при помощи установки/снятия модификатора. Изменение модификатора создает событие, которое можно использовать для работы с блоком.

Например, чтобы отметить чекбокс, блоку checkbox нужно установить модификатор checked в значение true.

В БЭМ-проекте нельзя изменять состояния в режиме runtime с помощью модификатора, напрямую меняя CSS-класс на соответствующем DOM-узле. Для корректной работы JavaScript все манипуляции с модификаторами должны производиться при помощи методов-хелперов.

Примеры реализации доступны в документации к i-bem.js.

Реакция на изменение модификаторов

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

В БЭМ реакция на установку/снятие модификатора описывается декларативно. Так, например, если в CSS во время исполнения появляется какой-то дополнительный класс (модификатор), то все свойства этого модификатора автоматически применяются к DOM-узлу, на который этот класс установлен. В JavaScript происходит то же самое: если появляется модификатор (добавляется новый класс к DOM-узлу), то вся функциональность, свойственная этому модификатору, применяется. Если модификатор исчезает, функциональность отключается.

Чтобы динамически изменять состояния блоков и элементов, используются специальные методы для установки и снятия модификаторов.

Примеры реализации доступны в документации к i-bem.js.

Пример

Рассмотрим форму отправки сообщения. Должно выполняться условие: если введен неправильный email, кнопка отправки (блок button) становится недоступна (получает модификатор button_disabled).

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

Можно задекларировать поведение блока и получить возможность перекрывать каждый модификатор отдельно на новом уровне переопределения. В декларации можно указать, как блок или элемент должен отреагировать на изменение модификатора.

block('button').onSetMod({
    focused: {
        true: this.onFocus,
        '': this.onBlur
    }
});

Такой подход дает возможность:

Разделение кода на части

К JavaScript могут применяться основные принципы организации и хранения кода по БЭМ-методологии:

Пример

Рассмотрим пример логотипа (блок logo), реализованного в двух технологиях: шаблоне и стилях.

HTML-реализация блока:

<a class="logo" href="/">Ваша крутая компания</a>

CSS-реализация блока:

.logo {
    width: 150px;
    height: 100px;
}

Блок logo в файловой структуре проекта:

logo/
    logo.css   # Внешний вид блока
    logo.tmpl  # Шаблоны для генерации HTML-представления блока

Добавим блоку logo JavaScript-функциональность: теперь нажатие на логотип вызывает какое-то действие. Согласно БЭМ-методологии новое поведение блока logo будет реализовано следующим образом:

JavaScript-реализация блока:

document.querySelector('.logo').addEventListener('click', doSomething, false);

Файл logo.js в файловой структуре блока:

logo/
    logo.css   # Внешний вид блока
    logo.tmpl  # Шаблоны для генерации HTML-представления блока
    logo.js    # Динамическое поведение блока в браузере

Разделение кода на части и строгая организация файловой системы проекта позволяет не только облегчить навигацию по проекту и повторное использование или перенос компонентов, но и работать с уровнями переопределения для JavaScript и использовать сборку.

Работа с уровнями переопределения

В описании БЭМ-методологии приведено много примеров, где конечная CSS-реализация блока собирается с разных уровней переопределения. Применение принципов БЭМ-методологии к JavaScript позволяет аналогичным образом разделять поведение блоков по разным уровням:

С помощью уровней переопределения можно создать универсальную JavaScript-библиотеку блоков и изменять ее на проектном уровне. Затем использовать сборку и включать в проект только необходимое поведение блоков.

Пример

Вернемся к примеру формы отправки сообщения:

block('button').onSetMod({
    focused: {
        true: this.onFocus,
        '': this.onBlur
    }
});

Запись с стиле БЭМ позволяет:

Для работы с уровнями переопределения в БЭМ можно использовать специализированный фреймворк, например, i-bem.js, так как он создан по требованиям БЭМ-методологии.

Как перейти на JavaScript по БЭМ

Самый быстрый путь — начать применять принципы БЭМ-методологии в своем проекте и получать первые результаты без использования специализированного фреймворка. Как это сделать на практике показано в статье БЭМ — это не только про CSS с примерами на jQuery.

Чтобы реализовать сразу все идеи БЭМ в вашем проекте, необходимо использовать фреймворк i-bem.js:

Если вы заметили ошибку или хотите чем-то дополнить статью, вы всегда можете или написать нам об этом на Гитхабе, или поправить статью с помощью prose.io.