Предназначен для описания поведения DOM элемента в BEM терминологии c использованием синтаксиса ES6
Библиотека состоит из следующих компонентов:
BEM.Block- абстрактный класс для описания поведения блокаBEM.Element- абстрактный класс для описания поведения элементаBEM.Collection- базовый класс коллекций блоковBEM.Registry- объект-хранилище для определенных bem-js блоковBEM.Config- экземпляр конфига
JS-реализация блока описывает поведение определённого класса элементов веб-интерфейса. В конкретных интерфейсах каждый
блок может быть представлен несколькими экземплярами. Экземпляр блока реализует функциональность своего класса и имеет
собственное, независимое состояние. Экземпляры одного блока объединяются в коллекции BEM.Collection этого блока
В терминах парадигмы объектно-ориентированного программирования:
- блок — класс;
- экземпляр блока — экземпляр класса.
Поведение блока описывается в JavaScript-файле блока (myblock.js).
В соответствии с ООП, вся функциональность блока реализуется модульно в методах блока.
Данный класс должен расширять абстрактный класс BEM.Block
Методы блока подразделяются на:
- статические методы и свойства.
- методы и свойства экземпляра блока;
Свойство должно содержать имя блока. Внимание! данное свойство должно быть обязательно переопределено.
Cвойство может содержать объект со списоком js-событий и их обработчиков, подписка на которые произойдет при инициализации блока. В качестве обработчика могут выступать:
- строка - будет вызван одноименный метод у экземпляра блока
- callback - будет вызван переданный callback
//...
static get live()
{
return {
'click': 'onClick',
}
}Свойство может содержать объект со списком событий и их обработчиков. Структура возвращаемого объекта должна быть сделующей:
//...
static get events()
{
return {
// список обработчиков при изменении модификаторов блока
'onMod': {
// данный callback будет вызван каждый раз когда будет изменен модификатор modName не зависимо от его значения
'modName': 'onModName',
// если необходима подписка на изменения модификатора с определенным значением
'modName2': {
'value1': 'onModNameValueOne',
'value2': 'onModNameValueTwo',
}
},
// список обработчиков при изменении модификаторов у эл-ов блока
'onElemMod': {
// Ключ - имя эл-та. Значение - структура аналогичная onMod
'elemName': {
'modName': 'onModName'
}
}
}
}Свойство может содержать авто-модификаторы перечисление через пробел Возможные значения
- hover
- focus
- press
При наступлении соответсвующих событий у блока будут автом. изменяться указанные модификаторы
Свойство может содержать список аттрибутов которые будут установлены при инициализации блока.
//...
static get events()
{
return {
'attrName': 'attrValue',
}
}Принудительная инициализация всех экземпляров блока на странице. По умолчанию инициализация экземпляра блока происходит при наступлении внутри него какого либо пользовательского события (навели мышку, кликнули и т.п). По умолчанию false
Ленивая инициализация.
Св-во может содержать кол-во милисекунд на которое будет отложена инициализация блока.
Например при значении св-ва 1000 вместе со свойством forced в значении true инициализация блока
произойдет через секунду после загрузки страницы. По умолчанию 0
Кешировать все выборки.
Если св-во содержит true, то при доступе к дочерним эл-ам все выборки будут сохранены в кеше.
Содержат ссылку на jQuery объект window, document, document.body соответственно
Создает новый DOM элемент и возвращает экземпляр блока для этого эл-та
Возвращает экземпляр блока
Создает новую коллекцию блоков данного типа. Для переопределения базовой коллекции блока нужно переопределить данный метод и в нем вернуть экземпляр своей коллекции коллекции
Метод возвращает коллекцию экземпляров блока на странице. Данная коллекция будет изменяться по мере инициализации новых блоков или их удалении
Возвращает BEM.Config
Метод регистрирует данный блок в реестре блоков. Должен быть обязательно вызван после определения класса.
// ...
class MyBlock extends BEM.Block
{
// ...
}
MyBlock.register();- self - ссылка на класс, для доступа к статическим методам и свойствам (аналог
staticв php) - parent - возвращает ссылку на родительский экземпляр блока.
- name - название блока/элемента
- $el - ссылка на jQuery объект блока/элемента
- el - ссылка на DomElement объект блока/элемента
- id - уникальный id экземпляра блока
- isBlock
- isElement
Конструктор класса. На вход принимает 2 параметра
- node - DomElement блока/элемента
- parms.cache - кэшировать выборки или нет
- parms.lazy - ленивая инициализация
- parms.role - ...
Параметр parms может быть указан в аттрибуте onclick ноды.
Метод удаляет экземпляр блока. Если переданный параметр имеет значение true, то вместе с удалением js объекта будет удален и html элемент ассоциированный с ним. По умолчанию true
Метод вызывается при инициализации экземпляра блока
Добавляет модификатор name со значением state
Удаляет модификатор name со значением state
Добавляет/удаляет модификатор name со значением state
Проверяет наличие модификатора name со значением state
Возвращает первый BEM.Element js элемент блока по его имени из коллекции эл-ов
Возвращает коллекцию BEM.Collection js элементов блока
Если в верстке используются миксины bem-блоков, то с помощью этого метода можно получить эзлемпляр миксованного блока
<div id="mixin-block" class="b-block-1 b-block-2">
</div>// ...
// переменная содержит экзепляр блока b-block-1
let block1 = MyBlock1.getInstance(node);
// переключились на другой блок миксина
let block2 = block1.asBlock('b-block-2');Возвращает jQuery объект выборки по селектору внутри блока. При переданом параметре force = true
при поиске результата не будет использован кеш
Возвращает jQuery объект коллекции элементов блоков
Возвращает jQuery объект первый из коллекции элементов блоков
Одна и та же функциональность может быть востребована в нескольких блоках проекта. Например, разные блоки могут обращаться за данными к бэкенду, используя AJAX, или совершать однотипные операции с DOM-деревом и т.д. Чтобы избежать ненужных повторов в коде, общую функциональность можно инкапсулировать в виде модулей, а затем добавлять к блокам.
В этом случае создаваемый блок объявляется как наследник существующего. Для этого нужно, так же как и в php просто
расширить класс существующего блока.
Для доступа к методам и свойствам родителького блока нужно использовать ключевое слово super (аналог parent в php)
import BEM from jquery.bem
class ParentBlock extends BEM.Block
{
// ...
foo()
{
// ...
}
}
class MyBlock extends ParentBlock
{
// ...
foo()
{
// вызываем родительский метод
super.foo.apply(this, arguments);
// ...
}
}При инициализации экземпляры блока одного типа помещаются коллекции BEM.Collection
Получить коллекцию можно с помощью статического метода getCollection у блока.
import MyBlock from myblock;
let items = MyBlock.getCollection()BEM.Collection реализует интерфейс Array
в связи с чем для работы доступны все методы Array.prototype.* ссылка,
Так же для удобства использования есть методы позволяющие производить операции над всеми элементами сразу:
- addMod(name[, state])
- delMod(name[, state])
- toggleMod(name, state)
- $el()
- byMod(name[, state]) - возвращает коллекцию с блоками отфильтрованными по модификатору
- invoke(fn, ...args) - вызывает метод
fnс аргументами args у каждого экземпляра коллекции - invokeArray(fn, args) - аналогично методу
invoke, за исключением того, что аргументы передаются в виде массива
Для переопределения коллекции необходимо создать свой класс коллекций, который бы расширял базовый BEM.Collection
// ...
class MyCollection extends BEM.Collection
{
otherMethod()
{
// ...
}
}Далее у блока необходимо переопределить статический метод makeCollection в котором вернуть экземпляр своей коллекции
class MyBlock extends BEM.Block
{
// ...
static makeCollection()
{
return new MyCollection.make();
}
}