我正在尝试使用RxJS进行弹出菜单,这是我停止的地方:http://jsbin.com/coqulamamo/1/edit?html,js,output
我已经映射到2个主要事件流menuActivation
和menuDeactivation
:
每当其任何一个孩子发出menuActivation
或mouseenter
时,focusin
都会发出一个弹出容器。menuDeactivation
在其第一个menuActivation
之后或下一次任何非后继元素发出mouseleave
时发出最后一个focusin
元素。
对于menuActivation
上的每个弹出容器,将附加active
类;对于menuDeactivation
上的每个元素,将从元素中删除active
类。
到目前为止,一切都很好。但是现在,如何防止过多的DOM操作?不需要激活已经激活的菜单,这同样适用于停用,但是我不想将状态保留在Rx.Subject中,页面上可以分布任何长度的弹出菜单。
我尝试了.distinctUntilChanged()
,但是当依次在menuActivation
和menuDeactivation
中发出弹出式容器时,下一次在menuActivation
上不再发出相同的弹出式窗口。
在menuActivation.distinctUntilChanged()
上投影后,是否有办法允许弹出式容器超过menuDeactivation
?
最佳答案
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,我对这种语言不太熟悉。
关于javascript - 如何正确应用distinctUntilChanged以最小化DOM操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31949317/