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

问题描述 投票:0回答:2

令我有点惊讶的是,为了监听元素尺寸(而不是窗口对象)的变化,我们必须使用一个名为

ResizeObserver
的新接口。虽然它看起来做得很好;这似乎与其他元素相关事件有点不同,只需添加一个侦听器即可使用这些事件。

以添加事件监听器为例,监听mouseover事件

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

为什么不简单地为元素上的调整大小事件添加一个新的监听器?

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

是为了避免与window

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
方法更好?

javascript dom resize addeventlistener window-resize
2个回答
11
投票

在此 PR 中进行了一次讨论,其中 W3C 技术架构小组尝试定义何时在 EventTarget 上使用观察者模式。这次讨论的结果记录在here,我引用第一个陈述:

一般来说,使用EventTarget和通知事件,而不是 观察者模式,除非 EventTarget 不能很好地适合您 特点。

使用观察者模式相对于

EventTarget的优点如下:

  1. 可以在观察时或创建时自定义实例。观察者的构造函数或其

    observe()

     方法可以采用选项,允许作者自定义每个回调的观察内容。这对于
    addEventListener()
    来说是不可能的。

  2. 使用 Observer 对象上的

    disconnect()

    unobserve()
     方法可以轻松停止监听多个回调。

  3. 您可以选择提供像

    takeRecords()

    这样的方法,它会立即获取相关数据,而不是等待事件触发。

  4. 因为观察者是单一用途的,所以您不需要指定事件类型。

具体谈谈

ResizeObserver

我认为

  • 第二点和第四点不太相关。它不会添加或删除任何重要的内容,我认为

    resize

     事件在这里会是一个更好的匹配。

  • 它仍然没有实现

    takeRecords()

    方法,所以3d点不相关

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

Event 模型。

此外,还可能存在性能问题或

不可避免的递归,但我没有找到任何有关它们的测量或解释。


6
投票
这是

提出的,但 Chrome 决定使用观察者模型来发布它,似乎主要是因为它比基于事件的实现快 10 倍https://groups.google.com/a/chromium.org/forum/ #!topic/blink-dev/z6ienONUb5A

现在为什么

确实如此,我不知道。

© www.soinside.com 2019 - 2024. All rights reserved.