📏

window.onresizeでスクロールに惑わされない

2023/05/05に公開

スクロールごとにwindow.resizeが実行されるブラウザに対抗して、document.onscrollを頼ったりResizeObserverに乗り換えたりしました。

window.addEventListener("resize", _onresize);

ビューポートの幅や高さが変わったときに実行したい処理があったのですが、スクロール時にアドレスバー等が出入りしてresizeイベントが発生するブラウザもあります。残念なことに今回はその程度の変化で頻繫に実行したくない処理だったので、対策を取りました。

document.onscroll

スクロールされたときに実行されます。

let documentIsScrolled = false;
window.addEventListener("scroll", () => documentIsScrolled = true);
window.addEventListener("scrollend", () => documentIsScrolled = false);
window.addEventListener("resize", event => {
    if (!documentIsScrolled) {
        _onresize(event);
    }
});

スクロールが完了したときに発生するscrollendイベントと組み合わせて、スクロールされていない間だけ処理を実行するようにしました。

ResizeObserver

要素の寸法が変更されたときにコールバック関数を実行してくれます。

const observer = new ResizeObserver(_callback);
for (const target of document.querySelectorAll(".target")) {
    observer.observe(target);
}

resizeイベントを使っていた理由を振り返って、本当に検出したかったものを思い出しました。今回、本当に知りたかったことは特定の要素の寸法の変化でした。これはresizeでは難しかったので、ResizeObserverに乗り換えresizeの利用をやめました。

Discussion