元素resize监听API

时间:2022-03-07 02:06:08

响应式网站/Web应用措施 按照视口巨细调解内容展示方法。这凡是通过CSS和media盘问来完成。当CSS表示欠好我们会使用Javascript。

好比document.addEventListener("resize",fun)或者Element的onresize属性。通过监听window.resize事件,Javascript DOM操纵与视口巨细连结同步。

但你会意识到,这甚至不包孕在窗口未被调解巨细但元素转变其巨细的情况。例如,添加新的子元素,设置元素的display样式none或类似的操纵会转变元素,其兄弟或祖先的巨细。

跟着响应式Web应用措施的普及,对响应式组件的需求也会增加。这些组件也需要有对resize事件做出响应。不幸的是,Web平台目前不供给组件跟踪其巨细的要领。

Current workarounds

一些应用措施实施便宜的调解巨细通知框架(例如:Polymer)。这种要领容易堕落,难以维护,,并且需要每个组件都实施便宜要领。

其他人巧妙的通过可以取代调解事件的事件来调解内容(例如:<a href="http://www.mamicode.com/https:/github.com/wnr/element-resize-detector">element-resize-detector</a>)。目前最优秀的要领都使用类似的技巧:

在组件中插入一个绝对定位的子项,并且以发出滚动事件的方法制作子项,或者在父项巨细变动时制作window.resize。

绝对定位的子项要领在ShadowDOM或React等框架中不起感化。

这些要领都不成取。它们在正确性,代码庞大性和性能方面都掉败了。

在当今的Web平台上无法复制ResizeObserver成果。

这就是为什么ResizeObserver是一个有用的原始API。它对任何不雅察看到的元素的巨细的变革作出反响,与导致变革的原因无关。它还为您供给访谒不雅察看元素的新巨细。

API

提到的“Observer”后缀的API共享一个简单的API设计。ResizeObserver也不例外。

您创建一个ResizeObserver 东西并将回调通报给结构函数。回调将被赋予一个数组ResizeOberverEntries- 每个不雅察看元素一个条目 - 包罗元素的巨细

var ro = new ResizeObserver( entries => { for (let entry of entries) { const cr = entry.contentRect; console.log(‘Element:‘, entry.target); console.log(`Element size: ${cr.width}px x ${cr.height}px`); console.log(`Element padding: ${cr.top}px ; ${cr.left}px`); } }); // Observe one or multiple elements ro.observe(someElement);

Usage examples

以下是使用ResizeObserver在画布内绘制椭圆的示例。

<canvas></canvas> <canvas></canvas> function drawEllipse(entry) { let ctx = entry.target.getContext(‘2d‘); let rx = Math.floor(entry.contentRect.width / 2); let ry = Math.floor(entry.contentRect.height / 2); ctx.beginPath(); ctx.clearRect(0,0, entry.contentRect.width,entry.contentRect.height); ctx.ellipse(rx, ry, rx, ry, 0, 0, 2 * Math.PI); ctx.stroke(); } // ResizeObserver delegates action to Element‘s handleResize method let ro = new ResizeObserver( entries => { for (let entry of entries) { if (entry.target.handleResize) entry.target.handleResize(entry); } }); // Set up observations var canvases = document.querySelectorAll(‘canvas‘); for (let canvas of canvases) { canvas.handleResize = drawEllipse; ro.observe(canvas); }

内联框架可以检测其巨细何时产生变革,并通知父窗口。

let ro = new ResizeObserver(entries => { let idealSize = computeIdealSize(); window.parent.postMessage({ name: "iframeResize", width: idealSize.width, height: idealSize.height }, ‘*‘); }); ro.observe(document.body);

当新动静达到时,我们如何让聊天窗口滚动到底部?ResizeObserver解决方案将所有动静生存在不停增长的中div,并不雅察看其巨细。当新动静达到时,滚动到底部。
完整的例子 详细讨论了用户滚动的措置惩罚惩罚。

.chat { overflow: scroll; } <div> <!-- chat has the scrollbar --> <div> <!-- chat-text contains chat text --> <div>jack: hi </div> <div>jill: hi </div> </div> </div let ro = new ResizeObserver( entries => { for (let e of entries) { let chat = e.target.parentNode; chat.scrollTop = chat.scrollHeight - chat.clientHeight; } }); ro.observe(document.querySelector(‘.chat-text‘))

How

元素resize监听API

Performance

调解通知的巨细可以有很高的频率。Observer API制止了事件捕获/泡泡的开销。

框架作者可以在ResizeObserver之上供给一个开发友好的“基于事件”的API,以制止注册太多的不雅察看者。

Notice

通知传送挨次

当多个ResizeObservers注册时,通知应按注册挨次传送。

回调变换集应按注册挨次列出元素。

内联元素

内联元素不应该生成调解巨细通知。

怎么样调动?

转换不会影响内容巨细。他们不应该触发通知。

动画怎么样?

影响内容巨细的动画应该会触发通知。

如果事情本钱很高,开发人员可能会但愿在动画期间跳过事情。

调解巨细和可视性