Upload
yandex
View
1.746
Download
11
Embed Size (px)
DESCRIPTION
Многие темы удобнее и интереснее изучать с помощью разных небольших примеров конкретных решений задач. Написание JavaScript для браузера с использованием i-bem.js – не исключение. Разберём задачи, основанные на реальной практике разных проектов Яндекса.
Citation preview
Я.Субботник, Москва, 8 сентября 2012 года
Варя Степановаруководитель группы разработки интерфейсов
БЭМ и JavaScript: Сборник рецептов
Вложенные блоки
4
Блоки b-menu-*
4
Блоки b-menu-*
5
Как работает b-menu-*?
this .trigger(‘current’);
6
b-seach
,nd*() методы
7
внутри
снаружи
на себе
BEM.DOM.decl('b-search', { onSetMod: { 'js': { 'inited': function() { this .findBlockInside( 'b-menu-vert') .on( 'current', this.doSmth() ); } } }}
8
...<div class="b-search__filter">
<div class="b-menu-vert i-bem" onclick="..."> ... </div>
</div>...
9
...
<div class="b-menu-vert i-bem b-search__filter" onclick="..."> ...</div>
...
10
this .findBlockInside( this.elem('filter'), 'b-menu-vert') .on('current', this.doSmth());
11
bit.ly/NfYdTa
12
Пример реиспользования меню
Декларативность
Декларативность в архитектуре
bit.ly/OptXT5
15
Презентация про Кнопочку на РИТ 2012
16
Состояния кнопки
16
Состояния кнопки
BEM.DOM.decl('b-form-button', { onSetMod : {
'focused' : {
'yes' : function() {
... this .bindTo('keydown', this._onKeyDown) .elem('input').focus();
17
18
b-map & i-geo-point
{ block: 'b-map',
mods: { ... },
js: { ... center: [ 37.58, 55.73 ], zoom: 16, points: [ ... ] }
}
19
Переопределение уровнем
Переопределение в CSS
22
library/blocks/b-head/b-head.css-----------------------------------------
.b-head { color: red; }
Переопределение в CSS
22
library/blocks/b-head/b-head.css-----------------------------------------
.b-head { color: red; }
blocks/b-head/b-head.css-----------------------------------------
.b-head { color: green; }
Переопределение в CSS
22
Переопределение динамического метода
b-9ash
24
b-9ash
24
getDefaultParams : function() {
return {
version : '10.0.0', width : '100%', height : '100%', attributes : {}, ... };
}
25
getDefaultParams : function() {
return {
version : '10.0.0', width : '50%', height : '50%', attributes : {}, ... };
}
26
getDefaultParams : function() {
return $.extend( this.__base(), { width: '50%', height: '50%' } );
}
27
Переопределение статического свойства
b-serp
29
b-serp
29
BEM.DOM.decl('b-serp', { // динамические поля}, { blocks: []});
blocks-common/b-serp/b-serp.js
30
blocks/b-serp/b-serp.jsBEM.DOM.decl('b-serp', {}, { blocks: [ 'b-form-input', 'b-adv', 'b-serp-list', 'b-more', 'b-feet' ]});
blocks-new/b-serp/b-serp.jsBEM.DOM.decl('b-serp', {}, { blocks: [ 'b-form-input', 'b-adv', 'b-filters', 'b-serp2-list', 'b-more', 'b-feet' ]});
31
Переопределение модификатором
b-form-input
33
b-form-inputb-form-input_autocomplete_yes
34
BEM.DOM.decl('b-form-input', { onSetMod : { 'js' : { 'inited' : function() { // инициализация } }, 'focused' : { 'yes' : { // что делать, когда в фокусе } } }}
35
36
BEM.DOM.decl({ block: 'b-form-input', modName: 'autocomplete', modVal: 'yes' },
36
BEM.DOM.decl({ block: 'b-form-input', modName: 'autocomplete', modVal: 'yes' }, { onSetMod: { 'js': { 'inited': function() { this.__base.apply(this, arguments); // расширение // функциональности }, ...
36
BEM.DOM.decl({ block: 'b-form-input', modName: 'autocomplete', modVal: 'yes' }, { onSetMod: { ...
37
BEM.DOM.decl({ block: 'b-form-input', modName: 'autocomplete', modVal: 'yes' }, { onSetMod: { ... 'focused': { 'yes': function() { this.__base(); // расширение //функциональности }, '': function() { ... }
37
live-события
39
39
BEM.DOM.decl('b-form-select', {...}, {
live: function() {
this.liveBindTo( 'item', 'mouseup', function() { ... }
}
});
40
live-инициализация
42
42
43
43
43
BEM.DOM.decl('b-block', { ... },
{ /* Статические методы и свойства */
}
);
44
BEM.DOM.decl('b-block', { ... },
{ live: function() { /* Когда инициализировать? */
}
}
45
live: function() {
this.liveInitOnEvent(...)
.liveInitOnBlockEvent(...)
.liveInitOnBlockInsideInit(...)
.liveInitOnBlockInsideEvent(...)
.liveInitOnBlockInit(...)
}
46
this
.liveBindTo('leftclick', function(e){ this._onClick(e); })
.liveBindTo( 'mouseover ... focusin', function(e) { var mod = eventsToMods[e.type]; this.setMod(mod.name, mod.val || ''); }); }
47
Миксование блоков
<div class="b-block1 b-block2 i-bem" onclick=" return { 'b-block1': {}, 'b-block2': {} } ">
Миксование блоков
49
<div class="b-domik b-c i-bem" onclick="return { 'b-domik' : {...}, 'b-c' : { .. } }"> ... <a class="b-domik__help"> Помощь </a> ...</div>
Блок сбора статистики кликов
50
baseBlock
52
Блоки b-menu-*
52
Блоки b-menu-*
BEM.DOM.decl('i-menu', {
onElemSetMod : {
'item' : { 'state' : { 'current' : function(...) { ... this.trigger('current'); } }
} }});
53
blocks-desktop/b-menu-horiz/b-menu-horiz.jsBEM.DOM.decl( { name: 'b-menu-horiz', baseBlock: 'i-menu' });
blocks-desktop/b-menu-vert/b-menu-vert.jsBEM.DOM.decl( { name: 'b-menu-vert', baseBlock: 'i-menu' });
54
55
bit.ly/Tq5aU4Блок i-menu
Распределённый :-) блок
Один и тот же блок
57
<div class="b-my-block i-bem" onclick="return { 'b-my-block' : { 'id' : 'myBlockId' } }"> <!-- smth --> </div>
<div class="b-my-block i-bem" onclick="return { 'b-my-block' : { 'id' : 'myBlockId' } }”> <!-- smth else --> </div>
58
b-tabbed-pane
59
<div class="b-tabbed-pane b-tabbed-pane__tabs i-bem" onclick="return {'b-tabbed-pane':{'id':'myTabbedPaneId'}}">
<div class="b-tabbed-pane b-tabbed-pane__panels i-bem" onclick="return {'b-tabbed-pane':{'id':'myTabbedPaneId'}}">
60
Блок без DOM-представления
BEM.decl('i-system', {
// динамические поля
}, {
// статические поля
});
62
BEM.decl('i-system', {
// динамические поля
}, {
// статические поля
});
BEM.DOM.decl(...)
62
channel
BEM.channel('channelName');
BEM .channel('channelName') .trigger('event');
BEM.channel('channelName').on();
BEM.channel('channelName').un();
channel API
64
var channel = BEM.channel('sys');
BEM.decl('i-system', {}, {
// каждые 50 милисекунд channel.trigger('tick');
// если активности нет channel.trigger('idle');
// при mousemove и keydown channel.trigger('wakeup');
});
65
BEM.DOM.decl('b-form-input', { 'js' : { 'inited' : function() { ... var sys = this.channel('sys').on({ 'tick' : update, 'idle' : function() { сhannel.un('tick', update); }, 'wakeup' : function() { сhannel.on('tick', update); } }); } },
66
67
update = function () { var inst, i = 0; while(inst = inst[i++]) inst.val(in.elem('input').val());}
67
update = function () { var inst, i = 0; while(inst = inst[i++]) inst.val(in.elem('input').val());}
BEM.DOM.decl('b-form-input', { ...
67
update = function () { var inst, i = 0; while(inst = inst[i++]) inst.val(in.elem('input').val());}
BEM.DOM.decl('b-form-input', { ... val : function(val, data) { if (val != oldVal) this.trigger('change', data); } ...});
67
bit.ly/OVJHhsБлок i-system, c примером
68
69