Войти с помощью github
Форум /

Блок 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/_/Kx6F6RQnQFitm0qRxX7vpvfP0K0.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/_/Kx6F6RQnQFitm0qRxX7vpvfP0K0.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/_/Kx6F6RQnQFitm0qRxX7vpvfP0K0.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-событие определённого блока.