2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

スクロールアニメーションに必要なあれこれ

Last updated at Posted at 2021-08-31

#概要
ウィンドウのスクロール量に応じて、表示・非表示を切り替えたり、マイクロインタラクションを入れたり、、などの実装をすることがよくありますが、scrollTop()offset().topなどが、毎回ごっちゃになるので、jQuery/JavaScriptでの各パラメータの取得方法をまとめました。

#基本的な考え方

##各パラメータの取得

ある要素が、スクロールによって、表示領域に入り、その後、表示領域から見えなくなるまでの動きを考えます。
図で表すと下記のようなイメージになります。
記事用 (3).jpg
図で示したパラメータの取得方法をざっくりまとめると下記のようになります。

|パラメータ| 内容 | jQueryで取得 |JavaScriptで取得 |
|:-:|:-:|:-:|:-:|:-:|
| A | ウィンドウのスクロール量 (ページの上端からの距離) |$(window).scrollTop()| window.pageYOffset |
| B | 表示領域の高さ |$(window).height()|document.documentElement.clientHeight|
| C | 要素の位置 (ページの上端からの距離)| $(elm).offset().top|elm.getBoundingClientRect().top|
| D | 要素の高さ| $(elm).outerHeight()|elm.getBoundingClientRect().height|

##表示条件の考え方

取得したパラメータを組み合わせ、条件式を組み立てます。

  • ある要素が表示領域に見え出したら: A + B > C
  • ある要素が表示領域に完全に表示されたら: A + B > C + D
  • ある要素が表示領域から見えなくなったら: A > C + D

#jQueryを使用する場合

##各パラメータの取得

A. ウィンドウのスクロール量の取得

index.js
let scrollPos = $(window).scrollTop();

ページの上端を基準とし、表示領域のスクロール位置(Y座標)をpx値で返します。

B. 表示領域の高さの取得

index.js
let winH = $(window).height();

メニューバーなどを含まない、表示領域の高さをpx値で返します。

C. 要素の位置の取得

index.js
let elmOffset = $('#box').offset().top;

offset()は、ある要素が配置されている位置を取得するメソッドです。
offset().topで、ページの上端を基準とし、要素の上端の位置(Y座標)をpx値で返します。

D. 要素の高さの取得

index.js
let elmH = $('#box').outerHeight();

outerHeight()で要素の高さをpx値で返します。これは、paddingやborderを含む外側の高さです。
optionで、outHeight(true)とすると、さらにmargin値を含む高さになります。
似たメソッドでinnerHeight()がありますが、これは、padding/borderを含まない内側の高さを返します。

##実装例

例として、スクロールによって、ある要素(#box3)が表示されると、追従ボタン(#sticky)を非表示になるようなサンプルを作成しました。

index.js
$(function() {
  let scrollPos; //スクロール量
  let elmOffset; //要素(#box3)の位置
  let winH = $(window).height(); //表示領域の高さ
  $(window).scroll(function() {
    scrollPos = $(window).scrollTop();
    elmOffset = $('#box3').offset().top;
    if (scrollPos + winH > elmOffset) {
      $('#sticky').removeClass('is-active');
    } else {
      $('#sticky').addClass('is-active');
    }
  });
  $(window).resize(function() {
    winH = $(window).height();
  });
})
index.html
   <div id="sticky is-active" class="sticky"></div>
   <div class="container">
    <div id="box1" class="box"><p>コンテンツ1</p></div>
    <div id="box2" class="box"><p>コンテンツ2</p></div>
    <div id="box3" class="box"><p>コンテンツ3</p></div>
   </div>
style.css
    .container {
      width: 1100px; 
      margin: 50px auto;
    }
    .container .box {
      height: 800px;
    }
    .sticky {
      position: fixed;
      bottom: -100px;
      left: 0;
      width: 100%;
      background: #ccc;
      height: 50px;
      transition: all 0.6s ease-in-out;
      z-index: 1;
    }
    .sticky.is-active {
      bottom: 0;
    }

#JavaScriptのみで実装する場合

##各パラメータの取得

A. ウィンドウのスクロール量の取得

index.js
let scrollPos = window.scrollY; //IE非対応
let scrollPos2 = window.pageYOffset;
let scrollPos3 = document.documentElement.scrollTop;

いずれも、ページの上端を基準とし、表示領域のスクロール位置(Y座標)をpx値で返します。

scrollY: https://developer.mozilla.org/ja/docs/Web/API/Window/scrollY
pageYOffset: https://developer.mozilla.org/en-US/docs/Web/API/Window/pageYOffset
scrollTop: https://developer.mozilla.org/ja/docs/Web/API/Element/scrollTop

B. 表示領域の高さの取得

index.js
let winH = document.documentElement.clientHeight;

メニューバーなどを含まない、表示エリアの高さをpx値で返します。
似たプロパティに、window.innerHeightがありますが、こちらは、水平スクロールバーの高さを含みます。また、window.outerHeightの場合は、ブラウザ のメニューバーなどを含む外側の高さを返します。

clientHeight: https://developer.mozilla.org/ja/docs/Web/API/Element/clientHeight
innerHeight: https://developer.mozilla.org/ja/docs/Web/API/Window/innerHeight
outerHeight: https://developer.mozilla.org/ja/docs/Web/API/Window/outerHeight

C. 要素の位置の取得

index.js
let elm = document.getElementById('box');
let elmOffset = elm.offsetTop;
let elmOffset2 = elm.getBoundingClientRect().top;

いずれもページの上端を基準とし、要素の上端の位置(Y座標)をpx値で返します。

offsetTop: https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/offsetTop
getBoundingClientRect: https://developer.mozilla.org/ja/docs/Web/API/Element/getBoundingClientRect

D. 要素の高さの取得

index.js
let elmH = elm.offsetHeight;
let elmH2 = elm.getBoundingClientRect().height;
let elmH3 = elm.clientHeight;  //border含まない

offsetHeightgetBoundingClientRect().heightは、Padding, borderを含む、要素の高さをpx値で返します。clientHeightの場合は、Paddingは含まれますが、borderは含まれません。

offsetHeight: https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/offsetHeight
getBoundingClientRect: https://developer.mozilla.org/ja/docs/Web/API/Element/getBoundingClientRect
clientHeight: https://developer.mozilla.org/ja/docs/Web/API/Element/clientHeight

##実装例
先ほどのjQueryでの実装例をJavaScriptで置き換えたサンプルです。

index.js
document.addEventListener('DOMContentLoaded', function() {
  let elm = document.getElementById('box3');
  let elmSticky = document.getElementById('sticky');
  let scrollPos;
  let elmOffset;
  let winH = document.documentElement.clientHeight;

  window.addEventListener('scroll', function() {
    scrollPos = window.pageYOffset;
    elmOffset = getBoundingClientRect().top;
    if (scrollPos + winH > elmOffset) {
      elmSticky.classList.remove('is-active');
    } else {
      elmSticky.classList.add('is-active');
    }
  })
  window.addEventListener('resize', function() {
    winH = document.documentElement.clientHeight;
  })
})
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?