Есть примерно следующая структура вложенных блоков:
{
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
Завел задачку: https://github.com/bem/bem-core/issues/1525