Форум

Методологія

Інструментарій

Платформа

Спільнота

Перевод этой статьи на ваш язык отсутствует, вы можете помочь нам перевести.

Состояния блока и элемента

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

Это позволяет писать код блока в декларативном стиле как набор утверждений вида:

  • «описание состояния» — «действия, выполняемые при переходе в данное состояние».

Модификаторы

Согласно БЭМ-методологии, состояние блока и его элементов описывается модификаторами.

Модификатор указывает, в каком из возможных состояний находится блок или элемент. Модификатор представляет собой пару: ключ-значение. Список допустимых значений модификатора описывает набор состояний блока и элемента. Например, для описания размеров блока можно использовать модификатор size с допустимыми значениями s, m и l.

Простой модификатор — частный случай, когда важно только наличие или отсутствие модификатора у блока или элемента, а его значение несущественно. Например, модификатор, описывающий состояние «отключен»: disabled. Модификатор с неуказанным значением i-bem.js интерпретирует как булев и автоматически присваивает ему значение true.

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

Модификаторы устанавливаются при инициализации экземпляра (если модификаторы и их значения указаны в атрибуте class соответствующего HTML-элемента).

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

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

Примечание Если модификаторы были заданы в HTML-элементе блока или элемента до момента его инициализации, триггеры на установку данных модификаторов не выполняются. Экземпляр в этом случае получает начальное состояние, а не меняет его.

Управление модификаторами

Методы экземпляра для работы с модификаторами:

  • hasMod(modName, [modVal]) – проверяет наличие модификатора. Возвращает true, если модификатор modName установлен.
  • getMod(modName) – возвращает значение модификатора modName.
  • setMod(modName, [modVal=true]) – устанавливает модификатор modName. Если значение modVal не задано, будет установлен простой модификатор.
  • toggleMod(modName, modVal1, [modVal2], [condition]) – переключает значения модификатора. Если передан аргумент [modVal2], переключение происходит между modVal1 и modVal2, если нет, modVal1 будет поочередно устанавливаться и удаляться. Аргумент condition в значении true позволяет инвертировать порядок переключения значений модификатора.
  • delMod(modName) – удаляет модификатор modName.

Пример

bemDom.declBlock('link', {
    // ...

    _onClick : function() {
        if(!this.hasMod('disabled')) {
            this._emit('click');
        }
    },

    _onFocus : function() {
        this.setMod('focused');
    },

    _onBlur : function() {
        this.delMod('focused');
    }

    // ...
});

Примечание Для изменения значений модификаторов используйте API. Не следует устанавливать модификаторы, самостоятельно изменяя CSS-классы соответствующего DOM-узла.

Полное описание API для управления модификаторами приведено в разделе JSDoc блока i-bem.

Триггеры на установку модификаторов

Выполнение триггеров на установку модификаторов разбито на две фазы:

  1. До установки модификатора. Эта фаза зарезервирована для возможности отменить установку модификатора. Если хотя бы один из триггеров, выполняемых в этой фазе, вернет false, установки модификатора не произойдет.
  2. После установки модификатора. Триггеры, выполняемые в этой фазе, уже не могут отменить установку модификаторов.

Триггеры могут быть привязаны к следующим типам изменений значений модификаторов:

  1. Установка любого модификатора в любое значение.
  2. Установка конкретного модификатора modName в любое значение (в том числе установка простого модификатора в значение true и удаление модификатора).
  3. Установка конкретного модификатора modName в конкретное значение modVal.
  4. Установка модификатора в значение '' (пустая строка), что эквивалентно удалению модификатора или установке простого модификатора в значение false.
  5. Установка конкретного модификатора modName в любое, отличное от конкретного значения modVal.
  6. Установка конкретного модификатора modName из конкретного значения modVal в любое другое.

При установке модификатора modName в значение modVal триггеры каждой фазы (если они определены) вызываются в том порядке, в котором они перечислены в приведенном выше списке событий (от общего к частному).

Таким образом, при определении триггера пользователь указывает:

  • фазу выполнения (до или после установки модификатора);
  • тип действия (имя и устанавливаемое значение модификатора).

Фазы выполнения

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

Пример

Модификатор focused не будет установлен блоку searchbox, если у него есть модификатор disabled.

bemDom.declBlock('searchbox', {
    beforeSetMod : {
        'focused' : {
            'true' : function() {
                return !this.hasMod('disabled');
            }
        }
    },

    onSetMod : {
        'focused' : {
            'true' : function() { /* ... */ }
        }
    }
});

Если триггер для фазы, предшествующей установке (beforeSetMod), возвращает false, установка модификатора не производится.

Подробнее об использовании триггеров читайте в разделе Декларация триггеров.

Примечание Триггер на установку модификатора js в значение inited является конструктором экземпляра блока, а в значение '' – деструктором экземпляра блока. Подробности смотрите в разделе Инициализация.

Якщо ви помітили помилку, або хочете доповнити статтю, ви завжди можете або написати нам про це на Гітхабі, або поправити статтю з допомогою prose.io.