javascript-过滤窗口上的事件与DOM节点上的单个事件

考虑以下代码示例:

import R from 'ramda';
import {Observable} from 'Rx';

var allClicks_ = Observable.fromEvent(window, 'click').share();

var getClicks = function(klass) {
  return allClicks_.filter(e => {
    return R.contains(klass, e.target.classList);
  });
};

getClicks('red').subscribe(x => {
  render('RED: ' + x.target.className);
});

getClicks('blue').subscribe(x => {
  render('BLUE: ' + x.target.className);
});

我没有将单击事件侦听器添加到“ .red”和“ .blue”,而是向窗口添加了事件侦听器并过滤了“ .red”和“ .blue”上的事件.

现在这样的代码会出什么问题?它比向单个DOM节点添加事件侦听器更有效(或更低)?还是没有性能优势?

编辑:共享热的Observable,以便仅附加一个事件处理程序.

解决方法:

这是委托事件处理程序的示例.此模式非常有用.实际上如此有用,以至于jQuery和dojo之类的库都对此模式提供了内置支持(请参见jQuery.ondojo.on的选择器参数).

向每个DOM节点添加事件处理程序实际上是O(n)操作,而这是O(1)操作.随着匹配的DOM节点数量的增加,委托事件处理程序模式实现了更大的收益.

有什么问题吗?

>如果在*元素(在本例中为窗口)和目标元素之间附加了事件处理程序,并且该事件处理程序执行ev.stopPropagation(),则委派的处理程序将永远不会看到该事件.
>如果您的过滤器功能过于复杂和缓慢,则浏览器将比平时运行过滤器花费更多的时间.
>在添加事件处理程序之后,您将获得针对DOM节点添加的事件.通常认为这是一件好事.但是,如果由于某种原因而没有想到,它可能会把您扔掉.

请注意,在您的特定示例中,实际上正在注册两个点击处理程序.您可以通过共享将其简化为单个实例:

var allClicks_ = Observable.fromEvent(window, 'click').share();
上一篇:javascript-使用RxJS将多个ajax请求转换为Observable


下一篇:javascript-RxJs处理异常而不终止