ResizeObserver
Baseline
広く利用可能
この機能は広く実装されており、多くのバージョンの端末やブラウザーで動作します。2020年7月以降、すべてのブラウザーで利用可能です。
ResizeObserver インターフェイスは、要素 (Element) のコンテンツまたは境界ボックス、または SVGElement のバウンディングボックスの大きさが変化したことを報告します。
メモ: コンテンツボックスは、コンテンツを配置できるボックスです。つまり、境界ボックスからパディングを引いたものです。境界とパディングの説明はボックスモデルを参照してください。
コンストラクター
ResizeObserver()-
新しい
ResizeObserverオブジェクトを作成して返します。
インスタンスプロパティ
なし。
インスタンスメソッド
ResizeObserver.disconnect()-
特定のオブザーバーの監視対象の
Elementをすべて監視解除します。 ResizeObserver.observe()-
指定された
Elementの監視を開始します。 ResizeObserver.unobserve()-
指定された
Elementの監視を終了します。
例
resize-observer-text.html (ソースを参照)の例では、スライダーの値が変更され、それを含む <div> の幅が変更されると、リサイズオブザーバーを使用してヘッダーと段落の font-size を変更します。これは、ビューポートに影響がない要素のサイズの変化にも応答することができることを示しています。
また、オブザーバーをオフやオンにするためのチェックボックスも用意しています。オフにすると、 <div> の幅が変化してもテキストは変化しません。
JavaScript は次のようになります。
const h1Elem = document.querySelector("h1");
const pElem = document.querySelector("p");
const divElem = document.querySelector("body > div");
const slider = document.querySelector('input[type="range"]');
const checkbox = document.querySelector('input[type="checkbox"]');
divElem.style.width = "600px";
slider.addEventListener("input", () => {
divElem.style.width = `${slider.value}px`;
});
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
if (entry.contentBoxSize) {
const contentBoxSize = entry.contentBoxSize[0];
h1Elem.style.fontSize = `${Math.max(
1.5,
contentBoxSize.inlineSize / 200,
)}rem`;
pElem.style.fontSize = `${Math.max(
1,
contentBoxSize.inlineSize / 600,
)}rem`;
} else {
h1Elem.style.fontSize = `${Math.max(
1.5,
entry.contentRect.width / 200,
)}rem`;
pElem.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`;
}
}
console.log("Size changed");
});
resizeObserver.observe(divElem);
checkbox.addEventListener("change", () => {
if (checkbox.checked) {
resizeObserver.observe(divElem);
} else {
resizeObserver.unobserve(divElem);
}
});
監視エラー
仕様に従う実装では、描画前(つまり、フレームがユーザーに表示される前)にリサイズイベントを呼び出します。リサイズ イベントがあった場合、スタイルとレイアウトが再評価され、さらにリサイズイベントが発生する可能性があります。循環的な依存関係による無限ループは、それぞれの反復処理中に DOM のより深い要素のみを処理することで対処します。この条件を満たさないリサイズイベントは次の描画に延期され、エラーイベントが Window オブジェクトに定義されたメッセージ文字列とともに発行されます。
ResizeObserver loop completed with undelivered notifications.
これはユーザーエージェントのロックを防ぐだけで、無限ループそのものを防ぐわけではないことに注意してください。例えば、次の例では divElem の幅が無限に広がり、コンソールに上記のようなエラーメッセージが毎フレーム発生します。
const divElem = document.querySelector("body > div");
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
entry.target.style.width = entry.contentBoxSize[0].inlineSize + 10 + "px";
}
});
window.addEventListener("error", function (e) {
console.error(e.message);
});
エラーイベントがいつまでも発行されない限り、リサイズオブザーバーは決定し、安定した、おそらく正しいレイアウトを生成します。しかし、訪問者は、単一のフレームで起こるはずの一連の変更が、複数のフレームにわたって起こるため、壊れたレイアウトがフラッシュして見えるかもしれません。
仕様書
| 仕様書 |
|---|
| Resize Observer> # resize-observer-interface> |
ブラウザーの互換性
関連情報
- ボックスモデル
PerformanceObserverIntersectionObserver(交差オブザーバー API の一部)- 今後リリースされるコンテナークエリーは、レスポンシブデザインを実装するための有効な選択肢になるかもしれません。