Block structure
JavaScript-enriched block
Prerequisites
Block i-bem and its dom element, with all their dependencies, must be included
into your page js file. This happens automatically if you borrow the project
structure from the project-stub repository.
HTML structure
Any BEM block can be equipped with JavaScript. To do this, you just need to place a JavaScript file into your block directory.
desktop.blocks/
my-block/
my-block.js
Then, just mark a block with a js flag when declaring it in BEMJSON.
{
block: 'my-block',
js: true
}
This gives (after running BEMHTML templates on the JSON) a corresponding DOM
node marked with an i-bem class and having data-bem attribute with the block
parameters.
<div class="my-block i-bem" data-bem="{'my-block':{}}">
...
</div>
If you are not using BEMHTML templates, instruct your templates to produce the same output or write this HTML manually.
The data-bem attribute stores block parameters in JSON, which structure is:
{
"my-block" : {
"paramName": "paramValue"
}
}
The console.log example
pure.bundles/
001-simple-block/
blocks/
my-block/
my-block.js
001-simple-block.bemjson.js
001-simple-block.html
The first example is the most simple. It demonstrates the block structure and shows how the JavaScript starts working.
Load the example page
001-simple-block with your console tool open, and you can see the outerHTML
of the my-block on the page.
The BEMJSON declaration of the example
001-simple-block.bemjson.js describes a simple page with only one
my-block component.
The my-block component is represented on the
001-simple-block/blocks level with a JavaScript file. The
my-block.js file is filled with a simple piece of code.
modules.define('my-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, {
onSetMod: {
'js' : {
'inited' : function() {
console.log(this.domElem[0].outerHTML);
}
}
}
}));
});
The i-bem framework utilizes a special module system ymaps/modules, so the first line defines which modules to use for the component.
In this case it is
i-bem__dom,
a module represented as a dom element of i-bem block from
bem-core library.
Inside you can use the BEMDOM object and its decl method to describe a block.
The block name is the first parameter.
The second is a hash of dynamic properties of the block. Every instance of the block gets a copy of them.
Aside from custom properties, the hash can also contain some special ones. You can
see one of them, an onSetMod property in the example. It is used to store
callbacks to run when a block gets a modifier.
BEMDOM.decl(this.name, {
onSetMod: {
'foo' : function() {
// Runs when a block gets any value of `foo` modifier.
// This also works for 'boolean' modifiers
},
'bar' : {
'qux' : function() {
// Runs when a block gets 'qux' value of 'bar' modifier
},
'' : function() {
// Runs when `bar` modifier is removed from a block
},
'*' : function() {
// Runs for any value of 'bar' modifier
}
},
'*' : function() {
// Runs for any modifier of the block
}
}
});
These callbacks get following parameters:
function(modName, modVal, currentModVal) {
// modName
// Modifier name is operated
// modVal
// Modifier value to be set. It is a `String` for modifiers with values
// or `true`/`false` for boolean modifiers
// currentModVal
// Current value of the modifier
}
The first modifier any block gets is a js modifier with its inited value.
The framework core reads all the i-bem marked blocks on a page and then
initializes them and sets the js_inited modifier on each block.
Thus, you can write a code to be run after the block starts functioning by defining
a callback to the js_inited modifier.
In the example presented above, this code is a console.log call with the block
outerHTML.