Блок b-link — это ссылка с различными модификаторами.
В простом случае для отображения блока необходимо задать следующий bemjson:
{
block: 'b-link',
url: 'http://company.yandex.ru',
title: 'Click here!',
target: '_blank',
content: 'The best company all over the world'
}
Свойство url преобразуется в атрибут href. Свойства title и target — в соотвествующие атрибуты.
В результате получается такой HTML:
<a
class="b-link"
href="http://company.yandex.ru"
title="Click here!" target="_blank">
The best company all over the world
</a>
Все эти преобразования возможны благодаря bemhtml-шаблону блока:
block b-link {
tag: 'a'
attrs: {
var ctx = this.ctx,
a = { href: ctx.url },
props = ['title', 'target'], p;
while(p = props.shift()) ctx[p] && (a[p] = ctx[p]);
return a;
}
}
Шаблон по моде tag определяет тег блока — <a>.
Шаблон по моде attrs копирует контент свойств и передает атрибутам в HTML.
Модификатор — mods: { pseudo: 'yes' }
Ссылка, подразумевающая действие без перехода на другую страницу. Визуально имеет пунктирное нижнее подчеркивание.
При наличии в bemjson у блока b-link свойства url HTML-тег блока следующий: <a href="...">...</a>
При отключенном js происходит переход по ссылке.
Чтобы использовать такую ссылку, нужно задать следующий bemjson:
{
block: 'b-link',
mods: { pseudo: 'yes' },
url: 'http://ya.ru',
content: 'Pseudo link'
}
Это даст следующий HTML:
<a
class="b-link b-link_pseudo_yes i-bem"
onclick="return {'b-link':{}}"
href="http://ya.ru">
<span class="b-link__inner">Pseudo link</span>
</a>
Ссылка без свойства url представлена в HTML тегом <span>.
В этом случае входные данные (bemjson) будут такими:
{
block: 'b-link',
mods: { pseudo: 'yes' },
content: 'Псевдоспан'
}
<span
class="b-link b-link_pseudo_yes i-bem"
onclick="return {'b-link':{}}">
<span class="b-link__inner">Псевдоспан</span>
</span>
bemhtml-шаблон для блока b-link с модификатором pseudo дополняет основной шаблон на b-link:
block b-link, this.mods.pseudo {
tag: (this.ctx.url? 'a' : 'span')
js: true
attrs, !this.ctx.url: {
return {}
},
content, !this.ctx._wrap, !this.mods.inner: {
local(
this._mode = '',
this.ctx = {
elem: 'inner',
content: this.ctx.content,
_wrap: true
}
) this.apply();
}
}
Шаблон по моде tag в зависимости от наличия свойства url устанавливает в качестве тега либо <a>, либо <span>.
Шаблон по моде js говорит о том, что у блока есть клиентский js.
Шаблон по моде attrs с дополнительным условием остутствия свойства url сбрасывает все атрибуты. Шаблон по моде content с дополнительными условиями — оборачивает контент псевдоссылки в элемент inner всегда, кроме случая, когда у блока есть модификатор inner.
Чтобы шаблон элемента inner был всегда у псевдоссылки, указываем зависимость в формате deps.js:
({
shouldDeps: [
{
elems: 'inner'
}
]
})
Секция shouldDeps подключает шаблоны на элемент inner после текущего блока.
Элемент — elem: 'inner'
Опциональный элемент. bemhtml-шаблон элемента inner для блока b-link.
block b-link, elem inner, tag: 'span'
Элемент inner представляется в HTML тегом <span>.
Модификатор — mods: { inner: 'yes' }
Позволяет добавлять в ссылку elem: 'inner'. Содержит только css, которые переносит подчеркивание с самой ссылки на ее внутренний элемент.
Описание блока с модификатором inner : yes в bemjson:
{
block: 'b-link',
mods: { inner: 'yes' },
url: '#',
content: [
{
block: 'b-icon',
mix: [ { block: 'b-link', elem: 'icon'} ],
url: 'https://yandex.st/lego/_/Kx6F6RQnQFitm0qRxX7vpvfP0 K0.png',
alt: 'Иконка Серпа'
},
{
elem: 'inner',
content: 'Ссылка с иконкой'
}
]
}
Элемент inner в формате bemjson может возникнуть только у ссылки с модификатором inner : yes, поэтому для данного модификатора указываем зависимость в формате deps.js так же, как для модификатора pseudo: 'yes'.
Одновременное использование модификаторов — mods: { pseudo: 'yes', inner: 'yes' }
Позволяет указывать элемент inner для псевдоссылки. Пример в формате bemjson:
{
block: 'b-link',
mods: { pseudo: 'yes', inner: 'yes' },
url: 'http://ya.ru',
content: [
{
block: 'b-icon',
mix: [ { block: 'b-link', elem: 'icon'} ],
url: 'https://yandex.st/lego/_/Kx6F6RQnQFitm0qRxX7vpvfP0 K0.png',
alt: 'Иконка Серпа'
},
{
elem: 'inner',
content: 'Псевдо-ссылка с иконкой'
}
]
}
<a
class="b-link b-link_pseudo_yes b-link_inner_yes i-bem"
onclick="return {'b-link':{}}"
href="http://ya.ru">
<img
class="b-icon b-link__icon"
src="https://yandex.st/lego/_/Kx6F6RQnQFitm0qRxX7vpvfP0 K0.png"
alt="Иконка Серпа"/>
<span class="b-link__inner">Псевдо-ссылка с иконкой</span>
</a>
Модификатор — mods: { disabled: 'yes' }
Неактивная ссылка или неактивная псевдоссылка.
js реализация блока
В техногии js реализовано поведение блока с модификатором pseudo : yes: github.com/.../b-link_pseudo_yes.js
Код написан под ядро клиентского js библиотеки блоков, реализованное в блоке i-bem. (bem.github.com/.../i-bem.ru.html)
Поведение блока описывается декларативно путём передачи параметров в метод BEM.DOM.decl.
Первый параметр - js-хеш, описывающий, к каким блокам должна быть применена данная js-реализация:
BEM.DOM.decl({'name': 'b-link', 'modName': 'pseudo', 'modVal': 'yes'}, {
...
В данном случае указано, что это js-поведение определено для блока b-link с модификатором pseudo в значении yes.
Первым параметром метода также может быть строка с именем блока, если сообщать modName и modVal не нужно.
Второй параметр метода запрашивает хеш динамических методов и свойств блока. В данном случае это только один метод _onClick:
_onClick : function(e) {
e.preventDefault();
this.hasMod('disabled', 'yes') || this.afterCurrentEvent(function() {
this.trigger('click');
});
}
_onClick() триггерит BEM-событие click на js-объекте блока. Это происходит только для активных ссылок (без модификатора disabled : yes) и в следующем потоке исполнения, для чего используется хелпер afterCurrentEvent.
Третий параметр в декларации блока — хеш статических методов и свойств. В данном случае определён зарезервированный статический метод live(), используемый для отложенной инициализации блоков.
В методе live() можно вызывать методы-хелперы для различных типов live-инициализации блока. В данном случае использован метод liveBindTo, позволяющий реагировать на DOM-событие определённого блока.