我有点惊讶的是,为了监听元素维度(而不是窗口对象)的更改,我们必须使用名为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
方法更好?
答案 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上使用观察者模式的优点如下:
可以在观察时或创建时自定义实例。观察者的构造函数或其
observe()
方法可以采用允许作者自定义每个回调观察到的内容的选项。addEventListener()
无法做到这一点。使用Observer对象上的
disconnect()
或unobserve()
方法停止监听多个回调很容易。您可以选择提供一种类似
takeRecords()
的方法,该方法可以立即获取相关数据,而不用等待事件触发。由于观察者是单一用途的,因此您无需指定事件类型。
专门讨论ResizeObserver
,我认为:
第二点和第四点不太相关。它并没有增加或采取任何至关重要的措施,我认为resize
事件在这里会更好。
它仍然没有实现takeRecords()
方法,因此3d点无关
它使我们能够在创建和观察时对其进行自定义,并允许以后更改这些自定义API,而无需更改Event模型。
此外,可能还有性能问题或an unavoidable recursion,但我没有发现有关这些问题的任何衡量标准或解释。