我正在尝试使用RxJS进行弹出菜单,这是我停止的地方:http://jsbin.com/coqulamamo/1/edit?html,js,output

我已经映射到2个主要事件流menuActivationmenuDeactivation


每当其任何一个孩子发出menuActivationmouseenter时,focusin都会发出一个弹出容器。
menuDeactivation在其第一个menuActivation之后或下一次任何非后继元素发出mouseleave时发出最后一个focusin元素。


对于menuActivation上的每个弹出容器,将附加active类;对于menuDeactivation上的每个元素,将从元素中删除active类。

到目前为止,一切都很好。但是现在,如何防止过多的DOM操作?不需要激活已经激活的菜单,这同样适用于停用,但是我不想将状态保留在Rx.Subject中,页面上可以分布任何长度的弹出菜单。

我尝试了.distinctUntilChanged(),但是当依次在menuActivationmenuDeactivation中发出弹出式容器时,下一次在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/

10-10 00:33