サイト制作に関するメモ書き

HOME > JavaScript > jQuery > 特定のスクロール範囲で要素を固定配置する

特定のスクロール範囲で要素を固定配置する

jQueryを使って特定のスクロール範囲のみ要素を固定配置するサンプルを実装してみます。

サンプルコード

まずは特定の位置以降に固定配置になる実装です。
ローカルナビをページ上部に固定するサンプルで試してみます。

HTML

<header>ヘッダー</header>
<main>
	<div class="mainvisual">
		メインビジュアル
	</div>
	<div class="local-nav-wrapper js-fix-wrapper">
		<ul class="local-nav js-fix">
			<li><a href="">ローカルナビ</a></li>
			<li><a href="">ローカルナビ</a></li>
			<li><a href="">ローカルナビ</a></li>
		</ul>
	</div>
	<section class="section1">
		<h2 class="ttl">コンテンツA</h2>
		<p>テキストテキストテキスト</p>
	</section>
	<section class="section2">
		<h2 class="ttl">コンテンツB</h2>
		<p>テキストテキストテキスト</p>
	</section>
	<section class="section3">
		<h2 class="ttl">コンテンツC</h2>
		<p>テキストテキストテキスト</p>
		<div class="share-btns">
			<a href="">シェアA</a>
			<a href="">シェアB</a>
			<a href="">シェアC</a>
		</div>
	</section>
</main>
<footer>フッター</footer>

.js-fix部分が固定配置になります。

CSS

.js-fix.is-fixed {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
}

固定配置の範囲にスクロールされたら.js-fixに.is-fixedを付与する想定です。
最後にJavaScriptです。

JavaScript

$(window).on('load scroll', function() {
  fix_element();
});

function fix_element() {
  // 固定配置に使用する要素
  var $fixWrapper = $('.js-fix-wrapper');
  var $fix = $('.js-fix');

  // 要素がある場合のみ処理
  if($fixWrapper.length && $fix.length) {
    var fixTop = $fixWrapper.offset().top;
    var winScroll = $(window).scrollTop();
    // 対象位置を通過している場合
    if(winScroll > fixTop) {
      $fix.addClass('is-fixed');
    } else {
      $fix.removeClass('is-fixed');
    }
  }
}

.js-fixを固定配置するとページ上部からの距離が変わってしまうので、親要素の.js-fix-wrapperの位置とスクロール位置を比較するようにしています。
これで特定位置以降までスクロールするとローカルナビが固定配置されるようになりました。
固定配置のデモページ1

次に特定位置にスクロールするまで固定配置する実装です。
シェアボタンをページ下部に固定するサンプルで試してみます。

HTML

<header>ヘッダー</header>
<main>
  <div class="mainvisual">
    メインビジュアル
  </div>
  <ul class="local-nav">
    <li><a href="">ローカルナビ</a></li>
    <li><a href="">ローカルナビ</a></li>
    <li><a href="">ローカルナビ</a></li>
  </ul>
  <section class="section1">
    <h2 class="ttl">コンテンツA</h2>
    <p>テキストテキストテキスト</p>
  </section>
  <section class="section2">
    <h2 class="ttl">コンテンツB</h2>
    <p>テキストテキストテキスト</p>
  </section>
  <section class="section3">
    <h2 class="ttl">コンテンツC</h2>
    <p>テキストテキストテキスト</p>
    <div class="share-btns-wrapper js-fix-wrapper">
      <div class="share-btns js-fix">
        <a href="">シェアA</a>
        <a href="">シェアB</a>
        <a href="">シェアC</a>
      </div>
    </div>
  </section>
</main>
<footer>フッター</footer>

基本的には前のサンプルと同じです。

CSS

.js-fix.is-fixed {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
}

こちらも前とほぼ同じで、今回は下部固定のためtopではなくbottomを指定しています。

JavaScript

$(window).on('load scroll', function() {
  fix_element();
});
  
function fix_element() {
  // 固定配置に使用する要素
  var $fixWrapper = $('.js-fix-wrapper');
  var $fix = $('.js-fix');

  // 要素がある場合のみ処理
  if($fixWrapper.length && $fix.length) {
    var fixTop = $fixWrapper.offset().top;
    var winScroll = $(window).scrollTop();
    var winheight = $(window).height();
    // 対象位置を通過していない場合
    if(winScroll + winheight < fixTop) {
      $fix.addClass('is-fixed');
    } else {
      $fix.removeClass('is-fixed');
    }
  }
}

画面下部で比較したかったのでスクロール位置 + 画面高さと固定要素を比較するようにしています。
固定配置のデモページ2

最後に特定範囲内のみ固定配置する実装です。
セクション内のみ見出しタイトルを上部に固定するサンプルで試してみます。

HTML

<header>ヘッダー</header>
<main>
  <div class="mainvisual">
    メインビジュアル
  </div>
  <ul class="local-nav">
    <li><a href="">ローカルナビ</a></li>
    <li><a href="">ローカルナビ</a></li>
    <li><a href="">ローカルナビ</a></li>
  </ul>
  <section class="section1">
    <h2 class="ttl">コンテンツA</h2>
    <p>テキストテキストテキスト</p>
  </section>
  <section class="section2 js-fix-area">
    <div class="ttl-wrapper js-fix-wrapper">
      <h2 class="ttl js-fix">コンテンツB</h2>
    </div>
    <p>テキストテキストテキスト</p>
  </section>
  <section class="section3">
    <h2 class="ttl">コンテンツC</h2>
    <p>テキストテキストテキスト</p>
    <div class="share-btns">
      <a href="">シェアA</a>
      <a href="">シェアB</a>
      <a href="">シェアC</a>
    </div>
  </section>
</main>
<footer>フッター</footer>

今回は固定する範囲を設定するためにsectionに.js-fix-areaを付与しています。

CSS

.js-fix.is-fixed {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}

上部固定のため最初のサンプルと同じです。

JavaScript

$(window).on('load scroll', function() {
  fix_element();
});

function fix_element() {
  // 固定配置に使用する要素
  var $fixWrapper = $('.js-fix-wrapper');
  var $fix = $('.js-fix');
  var $fixArea = $('.js-fix-area');

  // 要素がある場合のみ処理
  if($fixWrapper.length && $fix.length && $fixArea.length) {
    var fixTop = $fixWrapper.offset().top;
    var fixEnd = $fixArea.offset().top + $fixArea.height();
    var fixHeight = $fix.height();
    var winScroll = $(window).scrollTop();
    var winheight = $(window).height();
    // 開始位置を通過する前
    if(winScroll < fixTop) {
      $fix.removeClass('is-fixed');
    // 終了位置を通過した後
    } else if(winScroll > fixEnd - fixHeight) {
      $fix.removeClass('is-fixed');
    // 対象範囲内の場合
    } else {
      $fix.addClass('is-fixed');
    }
  }
}

固定するかの判別の考え方は前2つのサンプルとほぼ同じで、①固定開始と過ぎているかどうか ②固定終了位置を過ぎているかどうか ③それ以外(固定範囲) になります。
固定配置のデモページ3

今回はjQueryを使いましたが、固定条件や対象ブラウザによってはCSSのposition: stickyを使ってもいいと思います。
position: stickyの記事はこちら
 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

▲PAGE TOP