Web production note

 【更新日 :

【JavaScript】指定したエリア内で要素を追従させる機能を実装する

Category:
css / js

指定したエリア内で要素を追従させる機能をJavaScriptで実装したサンプルです。
overflow: hidden; などの問題で position: sticky; が利用出来ない時などに活用できます。

2026.01.23 更新箇所
追従要素がウィンドウの高さを超えている時に要素が見切れて見えなくなる問題があったため、ウィンドウの高さを超えているは追従の開始位置を要素の下端へ変更する設定を追加。

codepen

See the Pen Fixed within a designated area Vanilla JS by web_nak (@web_walking_nak) on CodePen.

JavaScript

//指定エリア内に要素を追従させる関数(追従要素,追従エリア)
const areaFixedFunk = (fixedElm,fixedArea) => {
	//エリアチェック
	const areas = document.querySelectorAll(fixedArea);
	if(areas.length === 0) {
		return;
	}
  
  //要素がウィンドウの高さを超えているか比較する用に取得
  let winHeight = 0;
  function getWindowHeight() {
    winHeight = window.innerHeight;
  }
  getWindowHeight();
  addEventListener('resize', getWindowHeight);

	//追従チェック関数
	const checkFixed = (target,area) => {
		//要素の位置と高さを取得
		let startPosi = area.getBoundingClientRect().top;
    let topValue = 0;
		const targetHeight = target.clientHeight;
		const areaHeight = area.clientHeight;
		const endPosi = startPosi + areaHeight;

    //winHeightとtargetHeightを比較して、targetHeightが大きい場合は差分上にずらす
    if(targetHeight > winHeight) {
      startPosi += (targetHeight - winHeight);
      topValue = winHeight - targetHeight;
    }

		//エリア内の処理
		if(0 > startPosi && targetHeight < endPosi) {
			target.classList.add('is-fixed');
			target.style.top = topValue + 'px';

		//エリアより上の処理
		} else if(0 <= startPosi) {
			target.classList.remove('is-fixed');
			target.style.top = '';

		//エリアより下の処理
		} else {
			target.classList.remove('is-fixed');
			//停止位置を設定
			target.style.top = (areaHeight - targetHeight) + 'px';
		}
	}

	//エリア毎に処理
	areas.forEach((area) => {
		//エリア内に追従要素が存在する場合のみ処理する
		const target = area.querySelector(fixedElm);
		if(target) {
			checkFixed(target,area);
			window.addEventListener('resize', ()=> {
				checkFixed(target,area);
			});
			window.addEventListener('scroll', ()=> {
				checkFixed(target,area);
			}, {passive: true});
		}
	});
}

HTML

追従させるエリア js-fixed-area と追従要素 js-fixed-area を準備します。

<div class="group-aside js-fixed-area">
  <div class="group-nav js-fixed-elm">
    <p>追従パーツ。js-fixed-areaの中でjs-fixed-elmが追従します。</p>
  </div>
</div>

CSS

.js-fixed-area {
  position: relative;
}
.js-fixed-elm {
  position: absolute;
  top: 0;
}
.js-fixed-elm.is-fixed {
  position: fixed;
}

関数の呼び出し

任意の場所で関数を呼び出してください。

//関数呼び出し(追従要素,追従エリア)
areaFixedFunk('.js-fixed-elm', '.js-fixed-area');
目次 を閉じる