如何为 DOM 操作最小化正确应用 distinctUntilChanged
How to correctly apply distinctUntilChanged for DOM operations minimization
我正在尝试使用 RxJS 做一个弹出菜单,这是我停止的地方:http://jsbin.com/coqulamamo/1/edit?html,js,output
我已经映射到 2 个主要事件流,menuActivation
和 menuDeactivation
:
menuActivation
每当它的子元素发出 mouseenter
或 focusin
. 时发出一个弹出容器
menuDeactivation
在其第一个 mouseleave
之后发出最后一个 menuActivation
元素,或者下一次任何非后代元素发出 focusin
.
对于 menuActivation
上的每个弹出容器,附加 active
class;对于 menuDeactivation
上的每个 active
class 都从元素中删除。
到目前为止,还不错。但是现在,如何防止过多的 DOM 操作?当菜单已经处于活动状态时不需要激活它,这同样适用于停用,但我不想将状态保持在 Rx.Subject 中,页面上可以分布任意长度的弹出菜单。
我尝试了 .distinctUntilChanged()
但是当弹出容器依次在 menuActivation
和 menuDeactivation
中发射时,下一次相同的弹出容器将不会在 [=11] 上发射=].
有没有办法让弹出容器在 menuDeactivation
上投影后超过 menuActivation.distinctUntilChanged()
?
distinctUntilChanged
只能在单个可观察对象上工作。要解决此问题,您可以创建一个结合了两个可观察对象的可观察对象。像
var menuAct2 = menuActivation.map(function(menu) { return { type: "act", menu: menu}; })
var menuDeact2 = menuDeactivation.map(function(menu) { return { type: "deact", menu: menu}; })
var actDeact = menuAct2.merge(menuDeact2)
.distinctUntilChanged(function (a) {return a;}, function (a, b) {
return a.menu === b.menu && a.type === b.type;
});
actDeact
.filter(function (a) { return a.type === "act";})
.map(function (a) {return a.menu;})
.subscribe(function(menu) {
console.log("Focou:", menu);
menu.classList.add("MainMenu__ListContainer--Active");
});
actDeact
.filter(function (a) { return a.type === "deact";})
.map(function (a) {return a.menu;})
.subscribe(function(menu) {
console.log("Desfocou:", menu);
menu.classList.remove("MainMenu__ListContainer--Active");
});
基本上,您通过合并两个可观察对象来创建一个可观察对象,对该可观察对象执行 distinctUntilChanged
,然后将其拆分回两个可观察对象以用于您的其余代码。
抱歉,如果这不合适javascript,我对这门语言不太熟悉。
我正在尝试使用 RxJS 做一个弹出菜单,这是我停止的地方:http://jsbin.com/coqulamamo/1/edit?html,js,output
我已经映射到 2 个主要事件流,menuActivation
和 menuDeactivation
:
menuActivation
每当它的子元素发出mouseenter
或focusin
. 时发出一个弹出容器
menuDeactivation
在其第一个mouseleave
之后发出最后一个menuActivation
元素,或者下一次任何非后代元素发出focusin
.
对于 menuActivation
上的每个弹出容器,附加 active
class;对于 menuDeactivation
上的每个 active
class 都从元素中删除。
到目前为止,还不错。但是现在,如何防止过多的 DOM 操作?当菜单已经处于活动状态时不需要激活它,这同样适用于停用,但我不想将状态保持在 Rx.Subject 中,页面上可以分布任意长度的弹出菜单。
我尝试了 .distinctUntilChanged()
但是当弹出容器依次在 menuActivation
和 menuDeactivation
中发射时,下一次相同的弹出容器将不会在 [=11] 上发射=].
有没有办法让弹出容器在 menuDeactivation
上投影后超过 menuActivation.distinctUntilChanged()
?
distinctUntilChanged
只能在单个可观察对象上工作。要解决此问题,您可以创建一个结合了两个可观察对象的可观察对象。像
var menuAct2 = menuActivation.map(function(menu) { return { type: "act", menu: menu}; })
var menuDeact2 = menuDeactivation.map(function(menu) { return { type: "deact", menu: menu}; })
var actDeact = menuAct2.merge(menuDeact2)
.distinctUntilChanged(function (a) {return a;}, function (a, b) {
return a.menu === b.menu && a.type === b.type;
});
actDeact
.filter(function (a) { return a.type === "act";})
.map(function (a) {return a.menu;})
.subscribe(function(menu) {
console.log("Focou:", menu);
menu.classList.add("MainMenu__ListContainer--Active");
});
actDeact
.filter(function (a) { return a.type === "deact";})
.map(function (a) {return a.menu;})
.subscribe(function(menu) {
console.log("Desfocou:", menu);
menu.classList.remove("MainMenu__ListContainer--Active");
});
基本上,您通过合并两个可观察对象来创建一个可观察对象,对该可观察对象执行 distinctUntilChanged
,然后将其拆分回两个可观察对象以用于您的其余代码。
抱歉,如果这不合适javascript,我对这门语言不太熟悉。