Владимир Гриненко "i-bem.js: javascript в БЭМ-терминах"
DESCRIPTION
Рассказ о том, как писать декларативный объектно-ориентированный JavaScript в БЭМ-терминах. Демонстрируются возможности блока i-bem из opensource библиотеки bem-bl для написания собственных блоков.TRANSCRIPT
Я.Субботник, Киев, 5 мая 2012 года
Разработчик интерфейсовВладимир Гриненко
i-bem.js: JavaScriptв БЭМ-терминах
2 года назад я пришел работать в Яндекс разработчиком интерфейсов главной страницы.Меня сразу же покусал Харисов
и с тех пор я перестал глядя на макет думать тегами.
Дизайнер ведь не рисует семантически верный хеадер,
<header></header><div> <div> <div> <span></span> <span></span> <span></span> </div> </div></div>
3
несколько вложенных друг в друга дивов (для обеспечения кроссбраузерности) и кучу спанов?Дизайнер рисует вполне реальные блоки,
с которыми будет взаимодействовать пользователь.Соответственно и реализовать нужно именно эти блоки, а не дивы и спаны.
Год назад я перешел в команду разработки общепортального фреймворка, из которого и вышел БЭМ, и Харисов покусал меня повторно.
В результате я подхватил БЭМ головного мозга и постараюсь покусать вас, а те, кто знает про gzip и не испугается длинных классов
великую они силу почувствуют.
clubs.ya.ru/bem/
Сейчас уже разработчики более-менее стали понимать, что БЭМ - это не про префикс b- хотя аватаром клуба до сих пор является эта иконка :)
На самом деле БЭМ – это методология,
<html>.css {javascript}
less
sass
haml
oocss
json
<xml/>
bootstrapкоторая охватывает все аспекты фронтэнд разработки и при желании в нее можно уложить и бекэнд.
i-bem.js
Я хочу поговорить о том, как писать javascript в терминах БЭМ.Для этого я буду использовать блок i-bem из библиотеки bem-bl, помогающий делать другие блоки.
Библиотека блоков bem-bl11
github.com/ bem/bem-bl
На слайде ссылка на репозиторий. Там же можно найти документацию по блоку i-bem.js.
Итак, в рамках доклада мы
— Рассмотрим БЭМ-методологию применительно к javascript
— Основные возможности фреймворка i-bem.js
— JS-реализацию карусели из Bootstrap
— До- и переопределим js-реализацию карусели у себя на проекте
Цели
12
1. Рассмотрим БЭМ-методологию применительно к javascript2. Основные возможности фреймворка i-bem.js3. JS-реализацию карусели из Bootstrap4. До- и переопределим js-реализацию карусели у себя на проекте
Давайте вспомним о чем говорит методология:1. Мы перестаем мыслить тегами. Вместо этого у нас появляются блоки.2. Блоки могут иметь элементы.
Состояние блоков и элементов может меняться с помощью модификаторов. Под состоянием нужно понимать как внешний вид (шаблоны, css), так и поведение (js). Т.о. у разработчиков, отвечающих за разные технологии, оказывается единая предметная область.
Благодаря разделению на уровни у нас появляется возможность реализовать библиотеку блоков и использовать сборку.
Как это работает в CSS понятно: стили из библиотеки доопределяются и переопределяются стилями проекта, страницы или темы оформления.
По БЭМ-методологии JS имеет все те же возможности.
Получается эдакий коктейль, где каждый уровень соответствующим образом переопределяет поведение ;)
i-bem.jsООП в полный рост
— классы и экземпляры
— полиморфизм и наследование за счет уровней переопределения
— инкапсуляция
Декларативный подход и предметная область БЭМ
16
Объект = Блок из предметной области БЭМ (нет классов и ДОМ-дерева)Все одинаковые блоки на странице - это класс, а каждый конкретный блок - это экземпляр данного класса.
Полиморфизм и наследование за счет уровней переопределения и модификаторов
Инкапсуляция – за счет получения больших составных блоков на основе нескольких маленьких
Декларативный подход (как в css)
Все эти возможности мы рассмотрим на примере блока из Бутстрапа
К сожалению в рамках доклада мы не успеем рассмотреть больше, чем один блок, поэтому я выбрал карусель – она перекликается с предыдущим докладом, является достаточно самостоятельным проектом и как раз позволит за 15 минут затронуть основные возможности i-bem.js
Итак, всем знакомая карусель состоит из контейнера какой-то ширины, каждый из вложенных элементов которого последовательно занимает всю ширину родителя, позволяет реализовать слайд-шоу и переключать «кадры» вручную.
github.com/tadatuta/ bootstrap-bl
Библиотека bootstrap-bl19
По ссылке находится репозиторий на гитхабе, где я с помощью короткого баш-скрипта переименовал блоки из Бутстрапа для соответствия БЭМ-нотации. Скрипт находится в этом же репозитории.
После перевода блоков в БЭМ-нотацию, оригинальная js-реализация по-прежнему осталась работоспособной. Но мы с вами напишем реализацию на i-bem.js для блока карусели. less остался без изменений и отлично собирается с помощью bem-tools
Важно понимать, что блоки из Бутстрапа – это лишь уровень переопределения в терминах БЭМ и методология гораздо шире, чем просто способ реиспользования кода.
BEM.DOM.decl('carousel', {
/* Динамические свойства и методы */
},{
/* Статические свойства и методы */
})
carousel.js20
Аналогично css - указываем правила поведения блоков, которые срабатывают при наступлении нужных условий.
Для реализации карусели нам понадобятся методы: cycle, etc.
BEM.DOM.decl('carousel', {
onSetMod : { 'mod' : { 'val' : function() { // Реакция на установку // значения модификатора } } }
})
21
чтобы навеситься на кнопки
clck.ru/1262j
i-bem.js — JSDoc22
Каждый метод i-bem.js сопровождается подробным описанием в jsdoc, так что можно легко разобраться даже не заглядывая в документацию.
/** * @protected * @param {jQuery|String} [elem] элемент * @param {String} event имя события * @param {Function} fn функция-обработчик, будет выполнена в контексте блока * @returns {BEM} */
bindTo : function(elem, event, fn)
23
Добавляет обработчик события на основные DOM-элементы блока или его вложенные элементы
/** * @protected * @param {String} names имя (или через пробел имена) вложенных элементов * @param {String} [modName] имя модификатора * @param {String} [modVal] значение модификатора * @returns {jQuery} DOM-элементы */
elem : function( names, modName, modVal)
24
Поиск вложенных в блок элементов (результат кэшируется)
/** * @protected * @param {Object} [elem] вложенный элемент * @param {String} modName имя модификатора * @param {String} [modVal] значение модификатора * @returns {Boolean} */
hasMod : function( elem, modName, modVal)
25
Проверяет наличие модификатора у блока/вложенного элемента
/** * @protected * @param {Object} [elem] вложенный элемент * @param {String} modName имя модификатора * @param {String} modVal значение модификатора * @returns {BEM} */
setMod : function(elem, modName, modVal)
26
Устанавливает модификатор у блока/вложенного элемента
/** * @protected * @param {Stringring|jQuery} [ctx=this.domElem] элемент, на котором проходит поиск * @param {String} names имя (или через пробел имена) вложенных элементов * @param {String} [modName] имя модификатора * @param {String} [modVal] значение модификатора * @returns {jQuery} DOM-элементы */
findElem : function( ctx, names, modName, modVal)
27
Поиск вложенных в блок элементов (результат не кэшируется)
/** * @protected * @param {String} e имя события * @param {Object} [data] дополнительные данные * @returns {BEM} */
trigger : function(e, data)
28
Запускает обработчики события у блока и обработчики live-событийtrigger — это БЭМ событие
/** * @protected * @param {Object} [elem] вложенный элемент * @param {String} modName имя модификатора * @returns {BEM} */
delMod : function(elem, modName)
29
Удаляет модификатор у блока/вложенного элемента
— Рассмотрели основные возможности блока i-bem.js— Реализовали карусель из Bootstrap в БЭМ-терминах— Переопределили javascript из библиотек блоков на уровне переопределения проекта
В результате
30
— Рассмотрели основные возможности блока i-bem.js
— Реализовали карусель из Twitter Bootstrap в БЭМ-терминах
— Научились переопределять javascript библиотек на уровне переопределения проекта
Разработчик интерфейсов
@tadatuta
Владимир Гриненко
github.com/tadatuta