スクロール・リサイズの検知

scroll resize ResizeObserver

スクロール位置やウィンドウサイズの変化を検知します。パフォーマンスを考慮したスロットリング・デバウンスも重要です。

現在の状態(リアルタイム)

scrollY
0px
現在のスクロール位置
window.innerWidth
0px
ウィンドウ幅(即時)
デバウンス後の幅
0px
300ms後に更新

ページをスクロールしたりウィンドウをリサイズしてみてください

コード例:基本の scroll / resize

js
// スクロール位置の取得
window.addEventListener('scroll', () => {
  console.log(window.scrollY);          // 垂直スクロール量
  console.log(window.scrollX);          // 水平スクロール量

  // 要素の位置
  const rect = el.getBoundingClientRect();
  console.log(rect.top);  // ビューポートからの距離
});

// ⚡ passive: true でパフォーマンス向上(推奨)
window.addEventListener('scroll', handler, { passive: true });

// ウィンドウリサイズ
window.addEventListener('resize', () => {
  console.log(window.innerWidth, window.innerHeight);
});

// スクロールを特定位置に移動
window.scrollTo({ top: 0, behavior: 'smooth' });    // スムーズにトップへ
window.scrollBy({ top: 100, behavior: 'smooth' });  // 相対的に移動
el.scrollIntoView({ behavior: 'smooth', block: 'center' }); // 要素を表示

比較:スロットリング vs デバウンス

scroll・resizeイベントは高頻度で発火するため、処理の間引きが重要です。

手法スロットリング(throttle)デバウンス(debounce)
動作一定間隔ごとに1回実行最後の呼び出しから一定時間後に1回実行
適した用途スクロール中の処理(スクロール位置追跡など)リサイズ完了後の処理、サジェスト検索
特性連続した更新が必要なとき最終状態だけが必要なとき
js
// スロットリング(100msに1回)
let lastTime = 0;
window.addEventListener('scroll', () => {
  const now = Date.now();
  if (now - lastTime > 100) {
    updatePosition();
    lastTime = now;
  }
});

// デバウンス(停止後300msで実行)
let timer;
window.addEventListener('resize', () => {
  clearTimeout(timer);
  timer = setTimeout(() => recalcLayout(), 300);
});

NEWResizeObserver(要素個別のサイズ変化を検知)

window.resize はウィンドウ全体のリサイズしか検知できませんが、ResizeObserver は特定要素のサイズ変化を検知できます。

js
const observer = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const { width, height } = entry.contentRect;
    console.log('要素サイズ変更:', width, height);

    // borderBoxSize(パディング・ボーダー含む)
    const boxSize = entry.borderBoxSize[0];
    console.log(boxSize.inlineSize, boxSize.blockSize);
  }
});

// 監視開始
observer.observe(document.querySelector('.resizable'));

// 監視停止
observer.unobserve(el);
observer.disconnect(); // 全て停止

🤖 AIプロンプトテンプレート

以下のようなscroll / resizeイベントとdebounce処理のサンプルコードを生成してください:
- scrollイベントとpassive: trueオプションでパフォーマンスを最適化する方法
- throttle関数を使ってscrollイベントを100msに1回に間引く実装
- debounce関数を使ってresizeイベント停止後300msで処理を実行するパターン
- ResizeObserverで特定要素のサイズ変化を監視する実装
- window.scrollTo / scrollBy / scrollIntoViewを使ったスクロール制御

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。