EN RU
Форум

Методология

Технологии

Инструментарий

Библиотеки

Учебные материалы

Работа с DOM-деревом

DOM-узел экземпляра блока и элемента

В контексте экземпляра блока и элемента с DOM-представлением зарезервировано поле this.domElem, содержащее jQuery-объект со ссылками на все DOM-узлы, с которыми связан данный экземпляр.

Поиск экземпляров блоков и элементов в DOM-дереве

Обращение к другому блоку в i-bem.js выполняется из текущего блока, размещенного на определенном узле DOM-дерева. Поиск других блоков в DOM-дереве может вестись по трём направлениям (осям) относительно DOM-узла текущего блока:

Сигнатура вспомогательных методов поиска блоков идентична:

Для методов поиска элементов:

Вспомогательные методы для поиска парные. Различаются возвращаемым значением:

Пример

modules.define('attach', ['i-bem-dom', 'button'], function(provide, bemDom, Button) {

provide(bemDom.declBlock(this.name, {
    onSetMod: {
        'js': {
            'inited' : function(modName, modVal) {
                this._button = this.findChildBlock(Button);
            }
        }
    }
}));

});

Примечание Не используйте jQuery-селекторы для поиска блоков и элементов. i-bem.js предоставляет высокоуровневое API для доступа к DOM-узлам блоков и элементов. Прямое обращение к DOM-дереву делает код менее устойчивым к изменениям БЭМ-библиотек и может привести к возникновению сложно обнаруживаемых ошибок.

Кэширующие методы поиска экземпляров элементов

Для оптимизации производительности для распространённых случаев поиска элементов одновременно по двум осям (внутри и на себе), служат кэширующие методы _elem(elem) и _elems(elem). Оба метода принимают один параметр:

Аналогично с некэширующими методами поиска кеширующие методы различаются возвращаемым значением:

Пример

modules.define('button', ['i-bem-dom', 'button__control'], function(provide, bemDom, ButtonControl) {

provide(bemDom.declBlock(this.name, {
    setName : function(name) {
        this._elem(ButtonControl).setName(name);
    },

    setValue : function(value) {
        this._elem(ButtonControl).setValue(value);
    }
}));

});

Примечание Результат кеширующих методов нет необходимости сохранять в переменную (см. предыдущий пример). В то время как для некеширующих методов хорошей практикой является единоразовый поиск всего, что нужно, с сохранением в переменную или внутреннее поле.

Примечание В случае использования элементов без JS реализации и динамического обновления DOM-дерева может понадобиться метод инвалидации кеша элементов _dropElemCache('elements'). Он принимает опциональный параметр с одним или несколькими именами элементов через пробел.

Кеширующий метод поиска экземпляра блока элемента

Пример

modules.define('my-form__submit-control', ['i-bem-dom'], function(provide, bemDom) {

provide(bemDom.declElem('my-form', 'submit-control', {
    _onClick : function() {
        this._block().submit();
    }
}));

});

Проверка вложенности

Динамическое обновление блоков и элементов в DOM-дереве

В модуле i-bem-dom предусмотрены следующие функции для добавления и замены фрагментов DOM-дерева.

Все функции возвращают DOM-элемент с содержимым для которого была выполнена инициализация для новых блоков и элементов.

Чтобы упростить создание БЭМ-сущностей на обновляемых фрагментах DOM-дерева, можно использовать шаблонизатор BEMHTML, подключив его в качестве ym-модуля. БЭМ-сущности описываются в формате BEMJSON непосредственно в коде блока. Функция BEMHTML.apply генерирует HTML-элементы по BEMJSON-декларации в соответствии с правилами именования БЭМ.

Пример

Метод _updateFileElem блока attach удаляет элемент file, если он существовал, и создает новый элемент с помощью функции BEMHTML.apply:

modules.define( 'attach', ['BEMHTML', 'i-bem-dom'], function(provide, BEMHTML, bemDom) {

provide(bemDom.declBlock(this.name, {
    _updateFileElem : function() {
        bemDom.replace(
            this._elem('file').domElem,
            BEMHTML.apply({
                block : 'attach',
                elem : 'file',
                content : this.getValue()
            }));
        return this;
    }
}));

});