Горизонтальное меню

{ block: 'b-menu-horiz' }

Блок b-menu-horiz создаёт HTML разметку для горизонтального меню. Кроме того, у блока есть JavaScript функциональность, позволяющая создавать скрипты с реакцией на выбор пункта меню.

Сложность HTML разметки меню зависит от модификатора, с которым используется блок.

Реализован модификатор блока layout с тремя возможными значениями:

  • horiz
  • complex
  • normal

Важно: Без модификатоора layout блок использоваться не может.

Модификаторы
_layout

_layout_complex

Горизонтальное меню с табличной разметкой

{ mods: { 'layout': 'complex' } }

Использование блока с модификатором { layout: 'complex' } принципиально ничем не отличается. Для блока в такой модификации создаётся разметка на основе таблицы. Такое решение может потребоваться при некоторых дизайнах.

_layout_normal

Простое горизонтальное меню списком

{ mods: { 'layout': 'normal' } }

Входные данные для блока с любым из этих модификаторов похожи: нужно описать блок, модификатор layout, в качестве свойства content блока перечислить пункты меню, которые выражаются элементами item:

{
  block: 'b-menu-horiz',
  mods: { layout: 'normal' },
  content: [
    {
      elem: 'item',
      content: 'Home'
    },
    {
      elem: 'item',
      content: 'Office'
    },
    ...
  ]
}

Содержанием элементов меню может быть что угодно: ссылки на страницы, псевдоссылки, иконки и вообще любые блоки. В примере выше каждый пункт меню — это просто строка текста.

Такое же меню со ссылками будет выглядеть следующим образом:

{
  block: 'b-menu-horiz',
  mods: { layout: 'normal' },
  content: [
    {
      elem: 'item',
      content: {
        block: 'b-link', url: '/', content: 'Home'
      }
    },
    {
      elem: 'item',
      content: {
        block: 'b-link', url: '/office', content: 'Office'
      }
    },
    ...
  ]
}

Кроме того, у одного из пунктов меню может быть указан модификатор { state: 'current' }, этот модификатор помечает текущий пункт меню.

На своём уровне переопределения можно реализовать для такого модификатора CSS правила, по которым текущий пункт меню будет визуально отличаться от остальных.

У меню также может быть необязательное свойство title, содержащее описание элемента title — заголовка меню.

Для меню с заголовком BEMJSON будет такой:

{
  block: 'b-menu-horiz',
  mods: { layout: 'normal' },
  title: {
    elem: 'title', content: 'Navigation:'
  },
  content: [
    {
      elem: 'item',
      elemMods: { state: 'current' },
      content: {
        block: 'b-link', url: '/', content: 'Home'
      }
    },
    {
      elem: 'item',
      content: {
        block: 'b-link', url: '/office', content: 'Office'
      }
    },
    ...
  ]
}

Горизонтальное меню с клиентской функциональностью

Не всегда меню на сайте подразумевает ссылки, уводящие пользователя на другую страницу. Меню может использоваться и для клиентского JavaScript приложения. В этом случае содержанием пунктов меню обычно бывают псевдоссылки:

{
  block: 'b-menu-horiz',
  mods: { layout: 'normal' },
  title: {
    elem: 'title', content: 'Navigation:'
  },
  content: [
    {
      elem: 'item',
      elemMods: { state: 'current' },
      content: {
        block: 'b-link',
        mods: { pseudo: 'yes' },
        url: '/',
        content: 'Home'
      }
    },
    {
      elem: 'item',
      content: {
        block: 'b-link',
        mods: { pseudo: 'yes' },
        url: '/office',
        content: 'Office'
      }
    },
    ...
  ]
}

Приведённый выше BEMJSON блока обеспечит нужный внешний вид.
Кроме этого нужно, чтобы у меню были области, реагирующие на клик. В данном случае они совпадают с псевдоссылками, поэтому можно применить смешивание блоков (mix):

{
  block: 'b-menu-horiz',
  mods: { layout: 'normal' },
  title: {
    elem: 'title', content: 'Navigation:'
  },
  content: [
    {
      elem: 'item',
      elemMods: { state: 'current' },
      content: {
        block: 'b-link',
        mods: { pseudo: 'yes' },
        mix: [{ block: 'b-menu-horiz', elem : 'item-selector' }],
        url: '/',
        content: 'Home'
      }
    },
    {
      elem: 'item',
      content: {
        block: 'b-link',
        mods: { pseudo: 'yes' },
        mix: [{ block: 'b-menu-horiz', elem : 'item-selector' }],
        url: '/office',
        content: 'Office'
      }
    },
    ...
  ]
}

JavaScript код блока реализован так, что активный пункт меню переключается при клике левой кнопкой мыши на соответствующем элементе item-selector.

При явном использовании этот элемент представлен в DOM в виде span, в который можно положить блоки, составляющие пункт меню. Если же содержание пункта меню состоит всего из одного блока (как в примере с псевдоссылками), для экономии разметки разумно применять mix.

Кроме того, что соответствующий элемент item в результате клика приобретает модификатор { state: 'current' }, на BEM объекте блока возникает событие current, сопровождающееся данными о текущем и предыдущем активных пунктах. В своём JavaScript приложении можно реагировать на это событие.

В HTML по умолчанию блок представлен как имеющий JavaScript реализацию (он смешан с блоком i-bem и имеет соответствующие параметры в атрибуте onclick). Но если в блоке отсутствуют элементы item-selector, BEM объект блока не создаётся.

Меню без подмешивания блока i-bem

{
  block: 'b-menu-horiz',
  js: false,
  mods: { layout: 'normal' },
  content: [
    {
      elem: 'item',
      content: {
        block: 'b-link', url: '/', content: 'Home'
      }
    },
    {
      elem: 'item',
      content: {
        block: 'b-link', url: '/office', content: 'Office'
      }
    },
    ...
  ]
}

Примешивание блока i-bem можно устранить, указав в свойстве js блока значение false.

_layout_simple

Горизонтальное меню простыми ссылками

{ mods: { 'layout': 'simple' } }

В некоторых случаях для вывода меню не нужны даже DOM узлы списка, а достаточно просто перечислить ссылки, разделив их пробелом, запятой или каким-либо специальным символом.

Для вывода такого меню подходит реализация с модификатором { layout: 'normal' }:

{
  block: 'b-menu-horiz',
  mods: { layout: 'simple' },
  separator: ' | ',
  content: [
    {
      elem: 'item',
      elemMods: { state: 'current' },
      content: 'Home'
    },
    {
      elem: 'item',
      content: {
      block: 'b-link',
      url: '/',
      content: 'Products'
    },
    ...
  ]
}

BEMJSON меню отличается наличием свойства separator — того самого специального символа, который разделяет пункты меню.
Активный пункт меню в данном примере представлен в виде простого текста в теге span.

Элементы
__item

Элемент меню

{ elem: 'item' }
__title

Заголовок меню

{ elem: 'title' }
Примеры

Простое горизонтальное меню

исходный кодскомпилированный код

Горизонтальное меню с табличной раскладкой

исходный кодуровень преопределенияскомпилированный код

Горизонтальное меню с JavaScript функциональностью

JavaScript реализация горизонтального меню позволяет динамически переключать активный пункт меню по клику левой кнопкой мыши.

Во время переключения на JS BEM-объекте, соответствующем меню создаётся событие current с данными о том, какой пункт меню выбран. Блоки, использующие меню, могут реагировать на это событие.

исходный кодуровень преопределенияскомпилированный код