こんにちは、ryohei(@ityryohei)です!

本記事では、JavaScriptでスクロールして要素が表示されたClassを追加する方法をご紹介しています。

画面内に要素が表示されたタイミングでClassを追加したいんだけど、良い方法ないかな?

上記の疑問にお答えしています。

本記事ではjQueryを使用せずにPureなJavaScriptのみで実現する方法をご紹介しています。jQueryにおいては下記の記事で実現方法をまとめていますので、参考にしていただれば幸いです。

では、解説していきます。

要素の位置を取得する方法

JavaScriptでビューポート内に存在する指定した要素の位置を取得するには、getBoundingClientRectを使用します。getBoundingClientRectはビューポートの左上を基準(0,0)として、指定した要素の座標を返すメソッドです。

実際には下記のように使用します。

element.getBoundingClientRect();

取得できる値は下記の通りです。

top要素の上部座標(Y軸)を取得する
bottom要素の下部座標(Y軸)を取得する
left要素の左部座標(X軸)を取得する
right要素の右部座標(X軸)を取得する

では、実際にgetBoundingClientRectを使用してスクロールして要素が表示されば際にClassを追加する処理を作成してみます。

スクロールして要素が表示されたらClassを追加する

下記が完成したスクリプトです。各行の処理内容につきましてはコメント記載しておりますので、参考にしていただければ!HTML側は重要ではないので割愛しています。

const myFunc = function(){

    //Classを追加する要素を取得
    const target = document.getElementsByClassName('target');
    //Classを追加する位置を指定(ビューポート内)
    const position = Math.floor(window.innerHeight * .75); //左記はビューポート内の上から75%の位置を指定

    //要素の数だけループする
    for (let i = 0; i < target.length; i++) {
        
        //要素の上部座標を取得する(小数点切り捨て)
        let offsetTop = Math.floor(target[i].getBoundingClientRect().top);

        //要素の上部座標がpositionの位置を通過したら
        if (offsetTop < position) {
            //要素にClassを追加する
            target[i].classList.add('is-animate');
        }
    }
}
//スクロールイベントリスナーに登録
window.addEventListener('scroll', myFunc, false);

上記を使用することでスクロールして要素が表示されたらClassを追加することができます!

要素がビューポート外に移動したら追加したClassを削除したい

そういった要望もあるかもしれないので併せてご紹介しておきます。

対象の要素の下部座標を取得し、下部座標が0未満(マイナス)になった場合に処理を実行して、追加したClassを削除します。そうすることで要素がビューポート外に移動した段階で追加したClassを削除することができます。

下記は前項でご紹介したスクリプトにClassを削除する処理を追加したものです。実装方法の一例として、参考にしていただければと思います。行が長くなるのでコメントは削除しています。

const myFunc = function(){

    const target = document.getElementsByClassName('target');
    const position = Math.floor(window.innerHeight * .75);

    for (let i = 0; i < target.length; i++) {

        let offsetTop = Math.floor(target[i].getBoundingClientRect().top);
        let offsetBottom = Math.floor(target[i].getBoundingClientRect().bottom);

        if (offsetTop < position) {
            target[i].classList.add('is-animate');
        }
        
        if(offsetBottom < 0){
            target[i].classList.remove('is-animate');
        }
    }
}
window.addEventListener('scroll', myFunc, false);

以上でスクロールで追加したClassの削除の完了です!

最後に

結構長くなるかな、と考えながら本記事でご紹介したスクリプトを作っていたのですが、出来上がった内容を見て、もしかしたらjQueryより短い行数で済んでいるかも?なんて思ってしまいました。まだまだ改善の余地はありますので、より良いものにできるように試行錯誤を続けていきたいと思います。

以上、JavaScriptでスクロールして要素が表示されたらClassを追加する方法のご紹介でした!