EN
lilliputten
lilliputten
4 сентября 2017

Есть примерно следующая структура вложенных блоков:

{
    block : 'box',
    mods : {
        root : true,
        id : 'layoutBox',
    },
    content : {
        block : 'box',
        mods : {
            id : 'appBox',
        },
        // Имеем некоторую вложенность блоков `box`: layoutBox->appBox->ReportLayout->Report->ReportDisplay; Т.е.:
        // ...
        content : {
            block : 'ReportDisplay',
            mix : {
                block : 'box',
                mods : {
                    id : 'ReportDisplay',
                },
            },
            content : {
                // Some content...
            },
        },
    },
}

При удалении блока ReportDisplay (при помощи BEMDOM.destruct(ReportDisplay.domElem)) по цепочке parentNode (в jquery) до верхнего уровня (layoutBox) всплывает событие на delMod('js'), в результате чего блок отписывается от событий, зарегистрированных на window (ранее подписываемся так: this._domEvents(BEMDOM.win).on('resize',...)).

Стек выглядит примерно так:

    (i-bem-dom__events.js:155) this._storage[e] = null; // e='resize' -- Это собственно удаление подписанного события в _unbindByEvent.
    // ...
    (i-bem-dom__events.js:139) objects.each(this._storage, this._unbindByEvent, this); // this._storage={resize:{uniq161:{...}}}
    (i-bem-dom__events.js:253) params.bindToArbitraryDomElem && ctxStorage[storageKey] &&
                            ctxStorage[storageKey].un();
    (i-bem-dom__events_type_bem.js:85) fn.call(fnCtx || instance, originalEvent, data); // fnCtx=null, instance=layoutBox, originalEvent={bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}, data={modName:'js', modVal:'',oldModVal:'inited'}
    (jquery:5205) ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||     //  handleObj.origType='__bem__box_js_'
                        handleObj.handler ).apply( matched.elem, args ); //  matched.elem=layoutBox.domElem[0], args=[jQuery.Event{type:'__bem__box_js_'},{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}]
    (jquery.js:5014) jQuery.event.dispatch.apply( elem, arguments ); // elem=layoutBox.domElem[0], ...
    (jquery:8201) handle.apply( cur, data ); // cur=layoutBox.domElem[0], data=[jQuery.Event{type:'__bem__box_js_'},{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}]
    (jquery.js:8262) jQuery.event.trigger(type, data, this); // type='__bem__box_js_', data=[{modName:'js', modVal:'',oldModVal:'inited'},{fns:{uniq151:true},propagationStoppedDomNode:null},{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}], this=ctx
    (jquery.js:8269) ctx.domElem.trigger(event, [data, { fns : {}, propagationStoppedDomNode : null }, originalEvent]); // event='__bem__box_js_', data={modName:'js',modVal:'',oldModVal:'inited'}, originalEvent:{bemTarget:ctx,data:undefined,target:ctx,type:'modchange'_isDefaultPrevented:false_isPropagationStopped:false}
    // ...
    (i-bem-dom.js:676) bemEvents.emit(this, e, data); // e={modName:'js',modVal:''}, data={modName:'js', modVal:'',oldModVal:'inited'}
    (i-bem-dom.js:733) this._emit({ modName : 'js', modVal : '' }, eventData); // eventData={modName:'js',modVal:'',oldModVal:'inited'}
    (i-bem.vanilla.js:324) this._afterSetMod('js', '', 'inited');
    (i-bem.vanilla.js:382) this.setMod('js', '');
    (i-bem.vanilla.js:247) this.delMod('js');
    (i-bem-dom.js:244) entity._delInitedMod();
    (i-bem-dom.js:1004) removeDomNodeFromEntity(entity, domNode);
    // ...
    (i-bem-dom.js:1029) this._destruct(ctx, excludeSelf, true);
    BEMDOM.destruct(ReportDisplay.domElem);

Полностью слепок вершины стека из DevTools, от destruct до _unbindByEvent).

_unbindByEvent (i-bem-dom__events.js:155)
each (objects.vanilla.js:56)
un (i-bem-dom__events.js:139)
(anonymous) (i-bem-dom__events.js:254)
inherit._createEventManager (i-bem-dom__events_type_bem.js:85)
dispatch (jquery.js:5206)
jQuery.event.add.elemData.handle (jquery.js:5014)
trigger (jquery.js:8201)
(anonymous) (jquery.js:8269)
each (jquery.js:362)
each (jquery.js:157)
trigger (jquery.js:8268)
emit (i-bem-dom__events_type_bem.js:119)
_emit (i-bem-dom.js:676)
_afterSetMod (i-bem-dom.js:733)
setMod (i-bem.vanilla.js:324)
delMod (i-bem.vanilla.js:382)
_delInitedMod (i-bem.vanilla.js:247)
removeDomNodeFromEntity (i-bem-dom.js:244)
(anonymous) (i-bem-dom.js:1004)
each (objects.vanilla.js:56)
(anonymous) (i-bem-dom.js:1000)
each (jquery.js:362)
each (jquery.js:157)
_destruct (i-bem-dom.js:993)
destruct (i-bem-dom.js:1029)

Т.е., раскрутить до конца я раскрутил, но вот дальше собственных мозгов разбраться, почему так происходит, как-то уже не хватает, увы. %((

Пока обхожусь принудительной переинициализацией событий на верхнем уровне после изменения содержимого.

Хелп? Что это может быть?

Версии библиотек:

  • bem-core@4.2.1
  • jquery@3.2.1
tadatuta
#tadatuta
5 сентября 2017