この記事では,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で実装する」の記事は終了です.
サンプルページのソースコードのダウンロードはこちらから行えます.