Binding JS blocks to HTML

JavaScript components in i-bem.js are used for bringing a page HTML elements to life. The typical task of a JS block is to set reactions to events inside an HTML fragment.

In i-bem.js, the primary ”framework“ is the document HTML tree. Points are marked in it where interactive interface elements, the JS blocks, are connected. The binding point for a JS block is an HTML element (DOM node) whose class attribute specifies the name of the block, and the data-bem attribute specifies the block parameters.

When loading a page in the browser, blocks are initialized. This creates instances of blocks — JS objects for all the blocks mentioned in classes of the page HTML elements. A JS object bound to an HTML element handles the DOM events that occur on it and stores the states of this block instance.

This method of binding JavaScript components to HTML has the following advantages:

Mechanism for binding blocks

To bind a block to an HTML element (for example, <div>...</div>), it is necessary to:

modules.define('my-block', ['i-bem__dom'], function(provide, BEMDOM){

        /* instance methods */
        /* static methods */


On the project level, each ym module is usually stored as a separate js file. For example, the my-block declaration might be stored in the project as my-block/my-block.js – the file my-block.js, inside the folder my-block.

The relation of blocks to HTML elements

A single HTML element doesn't have to correspond to a single block instance. The following relationships between blocks and HTML elements are possible:

One HTML element to one JS block

The simplest and most common way of binding blocks to HTML.


The div HTML element with my-block placed on it. Block parameters: an empty list {}.

<div class="my-block i-bem" data-bem="{ " my-block="my-block">

One HTML element to multiple JS blocks

The technique of placing multiple blocks on a single HTML element is called a mix in BEM methodology.


The div HTML element, with the following blocks on it:

<div class="user avatar i-bem" data-bem="{ " user="user">

One JS block to multiple HTML elements

This design is convenient if you need to coordinate the states of multiple components of a block.

To bind a block instance to multiple HTML elements, you must set the same value for the id parameter in the data-bem attribute. The value of id can be any string.


An instance of the notebook block bound to the div and span HTML elements. The parameters specify the shared id — maintab.

<div class="user avatar i-bem"
        "user": { "name": "pushkin" },
        "avatar": { "img": "http://..." }

As a result, when the blocks are initialized, a single JS object is created, with a domElem field that contains references to the jQuery objects of both DOM nodes.

For example, the ”tab“ widget, where a click on the tab title (the first HTML element) changes its content (the second HTML element). Another example is a placemark that marks a point on a map (the first element), and the related description of the point in the list next to it (the second element).

The id is used only at the time of initializing the block instance. The id value must be unique for instances of the same block in the context of a single wave of initialization.

Blocks without DOM representation

Infrastructure code that performs general interface tasks (access to the backend, or helper methods) can be formatted as a block. This allows expressing block states using modifiers, so that other blocks can subscribe to their changes.

To avoid binding these blocks to the HTML tree artificially, these blocks can be created in i-bem.js without DOM representation.

Blocks without DOM representation:

Access to block instances without DOM representation

When creating a block instance without DOM representation, you must see to it that references to this instance are stored for blocks that need to interact with it.

See also: