为什么引入`ResizeObserver`来监听调整大小更改而不是更简单的Element.prototype.addEventListener('调整大小',回调)

时间:2018-01-04 02:43:27

标签: javascript dom resize addeventlistener window-resize

我有点惊讶的是,为了监听元素维度(而不是窗口对象)的更改,我们必须使用名为ResizeObserver的新接口。虽然它似乎做得很好;它似乎与其他可以通过添加监听器消耗的元素相关事件有所不同。

例如,添加一个事件监听器来监听鼠标悬停事件

document.querySelector('#ele').addEventListener('mouseover', callback);

为什么不简单地在元素的resize事件中添加一个新的监听器?

document.querySelector('#ele').addEventListener('resize', callback);

是否避免与窗口resize事件发生冲突?如果是这样,为什么不用它来区别呢

document.querySelector('#ele').addEventListener('elementResize', callback);

我知道很容易创建一个辅助方法来简化ResizeObserver的使用。像这样的东西可以像原始addEventListener方法一样简单使用

export const getResizeObserver = ( ele, onResize ) => {
  let obs;

  const observerInterface = {
    stop: () => { obs.unobserve( ele ); obs.disconnect() },
  };

  obs = new ResizeObserver( entries => {
    for ( const entry of entries ) {
      onResize && onResize( entry.contentRect );
    }
  } );

  obs.observe( ele );

  return observerInterface;
};

// usage to add the listener
const obs = getResizeObserver(document.querySelector('#ele'), callback);
// later to remove the listener
obs.stop();

在任何情况下,除了api偏好以及几个元素可以共享观察者实例的事实之外,还有什么理由使得ResizeObserver方法比addEventListener方法更好?

2 个答案:

答案 0 :(得分:2)

这是proposed(问题仍然存在),但Chrome决定使用Observer模型发布此版本,似乎主要是因为它比基于事件https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/z6ienONUb5A的实现快10倍

为什么那是是真的,我不知道。

答案 1 :(得分:1)

有一个讨论in this PR,W3C技术架构小组试图定义何时在EventTarget上使用观察者模式。此讨论的输出记录在here中,我引用了第一条语句:

通常,使用EventTarget和通知事件,而不是 观察者模式,除非EventTarget不适用于您 功能。

EventTarget上使用观察者模式的优点如下:

  1. 可以在观察时或创建时自定义实例。观察者的构造函数或其observe()方法可以采用允许作者自定义每个回调观察到的内容的选项。 addEventListener()无法做到这一点。

  2. 使用Observer对象上的disconnect()unobserve()方法停止监听多个回调很容易。

  3. 您可以选择提供一种类似takeRecords()的方法,该方法可以立即获取相关数据,而不用等待事件触发。

  4. 由于观察者是单一用途的,因此您无需指定事件类型。

专门讨论ResizeObserver我认为

  • 第二点和第四点不太相关。它并没有增加或采取任何至关重要的措施,我认为resize事件在这里会更好。

  • 它仍然没有实现takeRecords()方法,因此3d点无关

它使我们能够在创建和观察时对其进行自定义,并允许以后更改这些自定义API,而无需更改Event模型。

此外,可能还有性能问题或an unavoidable recursion,但我没有发现有关这些问题的任何衡量标准或解释。