【jQuery】Webページにおける縦方向の現在位置を示すインジケーターをjQueryで実装する

  • LINEで送る

この記事では,Webページにおける縦方向の現在位置を示すインジケーターをjQueryで実装します.ウィンドウのスクロール量に応じてインジケータが指し示す点も上下に移動します.また現在のインジケーター以外のインジケーターをクリックすることで,その高さのウィンドウまで自動スクロールするように実装します.Webページ全長がとても長い場合等に有効な方法です.それではインジケーターの作り方を見ていきましょう.

サンプルページ

今回は上記の画像の赤枠部分を作っていきます.左側のスマホの図はWebページ最上部の時の画像で,その隣はスクロール後の画像です.インジケーターの配置は固定しておきます.スクロールに応じて,白い丸印が上下に移動します.また,インジケーターをクリックすると対応する高さまで自動スクロールするようにします.この画像ではスマホ用のページで表示してありますが,デスクトップなどの広い画面でも同じ機能です.それではコードを見ていきましょう.

HTML

<div id="height-indicator">
    <div class="top-to-bottom">
        <a href="#" id="top1"></a>
        <a href="#" id="top2"></a>
        <a href="#" id="top3"></a>
        <a href="#" id="top4"></a>
        <a href="#" id="top5"></a>
        <a href="#" id="top6"></a>
        <span></span>
    </div>
</div>

個々のインジケーターは<a>タグを利用して作成し,実際に上下に動く白色の丸印は<span>タグで実装しました.<a>タグにはidを設定しておきましょう.idを利用してどのインジケータが押されたか判別し,そのインジケーターに対応する場所に自動スクロールするための処理を実装します.

SCSS(CSS)

SCSSのコードは「$node-sass」コマンドでCSSファイルにコンパイルしましょう.コードは以下になります.

#height-indicator {
    position: fixed;
    width: 50px;
    height: 40vh;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    display: flex;
    justify-content: center;
    align-items: center;
    opacity: 0.5;

    .top-to-bottom {
        width: 6px;
        height: 35vh;
        border-radius: 4px;
        background-color: #1d1d1d;
        display: flex;
        position: relative;

        a {
            position: absolute;
            transform: translate(-50%,-9px);
            left: 50%;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background-color: #1d1d1d;
        }

        span {
            position: absolute;
            top: 0%;
            left: 50%;
            transform: translate(-50%,-50%);
            width: 12px;
            height: 12px;
            border-radius: 50%;
            background-color: white;
            transition: 0.5s;
        }
    }
}

インジケーターは常に同じ位置に固定しておきたいので,「#height-indicator」には{position:fixed}を指定しておきましょう.

<a>タグには{position:absolute}と横方向の位置のみを指定しています.個別の縦方向の位置は,CSSの「a:nth-of-child(1)」で指定できるのですが,冗長になるのでjQueryで指定しています.

<span>タグには初期位置の{top:0%}を指定しています.このタグはjQueryのanimate()メソッドで動かすわけではなく,速度の指定ができないcss()メソッドを利用するので,CSS側で{transition:0.5s}でアニメーション速度を指定しておきます.

jQuery(main.js)

//scrollTop()が適用される要素を取得する関数
function scrollableElement(){
    var i, len, el, $el, scrollable;
    for ( i = 0, len = arguments.length; i < len; i++){
        el = arguments[i],
        $el = $(el);
        if ($el.scrollTop() > 0){
            return el;
        } else {
            $el.scrollTop(1);
            scrollable = $el.scrollTop() > 0;
            $el.scrollTop(0);
            if (scrollable){
                return el;
            }
        }
    }
    return [];
}

//縦スクロール用のインジケーターの処理
$('#height-indicator').each(function(){

    var $body = $('body'),
        $window =$(window);
        $indicator_a = $(this).find('a'),
        $span = $(this).find('span'),

        len = $indicator_a.length;                //インジケーターの個数を取得
        
        body_height = $body.height(),             //webページ全体の縦幅
        window_height = $window.height(),         //画面に表示されるwindowの縦幅
        max_scroll = body_height - window_height, //スクロール可能な縦幅
        one_indicator = max_scroll / len,      //インジケーターを動かす1つの縦幅
        
    //インジケーターの配置
    $indicator_a.each(function(index){
        var move_amount = index * 100 / (len-1);
        $(this).css({
            'top': move_amount+'%'
        });
    })

    //インジケーターがクリックされた時に適当な場所にスクロールするイベント
    .on('click',function(){      
        var id = $(this).attr('id'); //インジケーターのidを取得
        switch (id){
            case 'top1': goToScroll(0); break;
            case 'top2': goToScroll(1); break;
            case 'top3': goToScroll(2); break;
            case 'top4': goToScroll(3); break;
            case 'top5': goToScroll(4); break;
            case 'top6': goToScroll(5); break;
        }
    });

    //windowにスクロールイベントを設定
    $(window).on('scroll',function(){
        //スクロール量を取得
        var scroll_height = $(this).scrollTop();
        switch(true) {
            case scroll_height < one_indicator:
                $span.css('top',0);    break;

            case scroll_height>=one_indicator && scroll_height<one_indicator*2:
                $span.css('top','20%');  break;

            case scroll_height>=one_indicator*2 && scroll_height<one_indicator*3:
                $span.css('top','40%');  break;

            case scroll_height>=one_indicator*3 && scroll_height<one_indicator*4:
                $span.css('top','60%');  break;

            case scroll_height>=one_indicator*4 && scroll_height<one_indicator*5:
                $span.css('top','80%');  break;

            case scroll_height>=one_indicator*5:
                $span.css('top','100%'); break; 
        }
        $window.trigger('scroll');
    });

    //自動スクロールの関数
    function goToScroll(index){
        //scrollTopが適用される要素を取得
        var body_or_html = scrollableElement('html','body');
        //インジケーターのindexに応じてスクロール量を調整
        $(body_or_html).animate({scrollTop: index*one_indicator+1+'px'},500);
    }
});

すこし長いですが,やっていることはそんなに難しくありません.説明はコメントアウトでコード内に載せていますが,重要なところだけ追加で解説します.へ変数のイメージは下記の図のような感じです.

scrollTop()メソッドはスクロールバーの上下の位置を指定できるメソッドです.animate()メソッド内で使用することで,自動スクロールすることもできます.しかし,開いているブラウザの種類によってはscrollTop()メソッドが適用される要素に違いがあります.FireFoxではhtmlに適用されますが,Google Chromeではbodyとhtmlどちらでも適用されます.他のブラウザは確認していませんが,適用される要素をこの関数を使って考慮しています.

インジケーターの<a>タグには2つの処理を行なっています.1つは縦方向の位置の設定で,2つ目は個々のインジケーターのクリックイベントです.indexには0〜5までの番号が振られます.それを使用して配置する高さを指定しています.クリックイベントのコールバック関数にはgoToScroll()関数による処理が行われます.引数に<a>タグのインデックスを指定することで自動スクロールするようになっています.

さらにwindowに対してスクロールイベントを設定し,switch文で<span>タグの配置を場合分けしています.

以上で「Webページにおける縦方向の現在位置を示すインジケーターをjQueryで実装する」の記事は終了です.

サンプルページはこちらからも閲覧できます.

サンプルページのソースコードのダウンロードはこちらから行えます.

SNSでもご購読できます。

コメントを残す

*