如何为 DOM 操作最小化正确应用 distinctUntilChanged

How to correctly apply distinctUntilChanged for DOM operations minimization

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

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

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

到目前为止,还不错。但是现在,如何防止过多的 DOM 操作?当菜单已经处于活动状态时不需要激活它,这同样适用于停用,但我不想将状态保持在 Rx.Subject 中,页面上可以分布任意长度的弹出菜单。

我尝试了 .distinctUntilChanged() 但是当弹出容器依次在 menuActivationmenuDeactivation 中发射时,下一次相同的弹出容器将不会在 [=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,我对这门语言不太熟悉。