Состояния блока и элемента
Проектируя динамический блок или элемент в стиле БЭМ, нужно представить всю логику изменений, происходящих в нем, как набор состояний. Тогда поведение блока и элемента определяется триггерами — 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
.
Триггеры на установку модификаторов
Выполнение триггеров на установку модификаторов разбито на две фазы:
До установки модификатора. Эта фаза зарезервирована для возможности отменить установку модификатора. Если хотя бы один из триггеров, выполняемых в этой фазе, вернет
false
, установки модификатора не произойдет.После установки модификатора. Триггеры, выполняемые в этой фазе, уже не могут отменить установку модификаторов.
Триггеры могут быть привязаны к следующим типам изменений значений модификаторов:
Установка любого модификатора в любое значение.
Установка конкретного модификатора
modName
в любое значение (в том числе установка простого модификатора в значениеtrue
и удаление модификатора).Установка конкретного модификатора
modName
в конкретное значениеmodVal
.Установка модификатора в значение
''
(пустая строка), что эквивалентно удалению модификатора или установке простого модификатора в значениеfalse
.Установка конкретного модификатора
modName
в любое, отличное от конкретного значенияmodVal
.Установка конкретного модификатора
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
является конструктором экземпляра блока, а в значение''
– деструктором экземпляра блока. Подробности смотрите в разделе Инициализация.