Webサイト

スクロールで動くサイドバーとフッターの挙動を制御する方法:jQueryとJavaScriptで実装

スクロールで動くサイドバーとフッターの挙動を制御する方法:jQueryとJavaScriptで実装

このコードスニペットは、特にWordPressやその他のWeb開発でよく使用されるjQueryを活用した機能的な例です。Webサイトのサイドバーやフッターの動的な振る舞いを制御するための非常に便利な方法を示しており、ページのレイアウトがスクロール時にどのように影響を受けるかについての理解を深めることができます。

本記事では、フッターが表示されているか、または display: none; に設定されているかに応じて、サイドバーの位置を動的に調整するスクリプトの解説を行います。また、フッターが画面に表示されない場合にも適切に機能するような処理を加えた、より汎用的なコードに書き換える方法についても説明します。

スクロール時のサイドバーの挙動

まず、元のコードの機能について説明しましょう。このコードは、ページがスクロールされたときに、フッターの位置に応じてサイドバーの位置を調整するために使用されます。特定の条件下では、スクロールがフッターに達すると、サイドバーを固定表示から絶対位置に切り替え、スクロールを解除します。以下が元のコードの基本的な流れです。

$(function() {
    let $window = $(window);
    let $sidebar = $('#sidebar');
    let $footer = $('footer');

    $window.scroll(function() {
        if ($window.scrollTop() + $window.height() > $footer.offset().top) {
            $sidebar.css({"position": "absolute", "bottom": "0", "top": "unset"});
        } else {
            $sidebar.css('position', 'fixed');
        }
    });
});

このコードが行っていることは、window(ブラウザの表示領域)がスクロールされるたびに、フッターの位置と比較してサイドバーの位置を変更することです。具体的には、以下のプロセスで処理が行われています。

  1. 変数の定義: $(window) でブラウザのウィンドウオブジェクトを取得し、#sidebar でサイドバーを取得、footer タグをフッターとして取得しています。
  2. スクロールイベント: ユーザーがスクロールするたびに、スクロール位置とフッターの位置が比較されます。
  3. フッターの位置に到達したときの挙動: スクロール位置がフッターに達すると、サイドバーの positionabsolute に変更され、画面下部に固定されます。逆に、スクロールがフッターに達していない場合は、サイドバーが fixed のままになり、スクロールに追従します。

フッターが表示されていない場合の処理

元のコードでは、フッターが存在する前提で処理が行われています。しかし、実際にはWebページのレイアウトによってはフッターが display: none; で非表示になっていることがあります。この場合、現在のコードでは正常に動作しません。そのため、フッターが表示されていない場合にも対応するために、コードに条件分岐を追加します。

フッターの表示状態を確認するために、$footer.is(':visible') メソッドを使います。このメソッドは、フッターが表示されているかどうかをチェックし、表示されていない場合はサイドバーがスクロールに追従する固定状態 (position: fixed) を維持するようにします。以下が修正後のコードです。

$(function() {
    let $window = $(window);
    let $sidebar = $('#sidebar');
    let $footer = $('footer');

    if ($footer.is(':visible')) {
        // フッターが表示されている場合の処理
        $window.scroll(function() {
            if ($window.scrollTop() + $window.height() > $footer.offset().top) {
                $sidebar.css({"position": "absolute", "bottom": "0", "top": "unset"});
            } else {
                $sidebar.css('position', 'fixed');
            }
        });
    } else {
        // フッターが非表示の場合の処理
        $window.scroll(function() {
            $sidebar.css('position', 'fixed');
        });
    }
});

このコードは、まずフッターが表示されているかを確認し、その結果に応じてサイドバーの位置を動的に調整します。$footer.is(':visible') でフッターの可視性を判定し、表示されている場合はフッターに達した時点でサイドバーを absolute に変更し、非表示の場合は常に fixed のままにします。

このアプローチの利点

このようなスクリプトを使うことで、フッターがあるページやないページの両方で、サイドバーがページのスクロールに応じて適切な動作を行うようになります。特にWebサイトのレイアウトが多様で、フッターの表示/非表示が動的に変わる場合には、非常に役立ちます。

さらに、このコードの拡張性は高く、フッターだけでなく他の要素に対しても同様の処理を適用できます。たとえば、ページ内の特定のセクションにスクロールが到達した際にサイドバーの挙動を変えるような処理にも応用できます。

display: none; の場合の注意点

display: none; になっている要素はDOMには存在しますが、レイアウトに影響を与えません。そのため、offset().top を使用して位置を取得しようとしても、その要素は「見えない」ため、正しい値を返さない可能性があります。しかし、このスクリプトは is(':visible') を使ってフッターの可視性を確認するため、フッターが表示されていない場合はその分岐に従い、通常のスクロール動作が保持されます。

また、display: none; になっている要素のスタイルが変更されて再び表示されるようになった場合でも、上記のコードでは動的にフッターの状態をチェックしているため、サイドバーの位置は自動的に調整されます。

jQueryの使用と現代的なアプローチ

jQueryは長らくWeb開発において広く使用されてきたライブラリですが、最近ではJavaScript自体の進化に伴い、ネイティブなDOM操作やイベントハンドリングも非常に簡単になっています。そのため、同じロジックをネイティブJavaScriptで書き換えることもできます。以下は、ネイティブJavaScriptでの同様の処理です。

document.addEventListener('DOMContentLoaded', function() {
    var windowEl = window;
    var sidebar = document.getElementById('sidebar');
    var footer = document.querySelector('footer');

    function checkFooterVisibility() {
        var footerStyle = window.getComputedStyle(footer);
        return footerStyle.display !== 'none';
    }

    if (checkFooterVisibility()) {
        windowEl.addEventListener('scroll', function() {
            if (windowEl.scrollY + windowEl.innerHeight > footer.offsetTop) {
                sidebar.style.position = 'absolute';
                sidebar.style.bottom = '0';
                sidebar.style.top = 'unset';
            } else {
                sidebar.style.position = 'fixed';
            }
        });
    } else {
        windowEl.addEventListener('scroll', function() {
            sidebar.style.position = 'fixed';
        });
    }
});

これにより、jQueryに依存せず、モダンなJavaScriptで同じ結果が得られます。