(jQuery版) ページ内リンクをクリックでスクロール移動。
jQueryを使って、アンカーリンクがクリックされたらページ内の任意の位置にスクロールアニメーションで移動させる方法。
HTMLのマークアップ
移動したい位置にあるHTML要素に任意のid属性を付ける。
ナビゲーションメニューなどでa要素のhref属性に、移動先のHTML要素のidと同じ文字列を「#」を付けてフラグメント識別子として指定。
<header>
<nav>
<a href="#test01">リンク01</a>
<a href="#test02">リンク02</a>
</nav>
</header>
<div id="test01">
<p>ターゲット01</p>
</div>
<div id="test02">
<p>ターゲット02</p>
</div>
jQueryで実装
a要素をクリックして、href属性の値が「#」から始まる文字列だった場合のみ、指定のidを持つ要素までスクロール移動させる。
実行させる操作の手順。
- a要素のhref属性値を取得。
- 取得したhref属性値と同じid属性値を持つHTML要素のY座標トップを取得。
- animate()メソッドでスクロール移動。
- ヘッダーが上部に固定されているデザインの場合はスクロール位置を補正。
関数を作成してクリックイベントで実行
- 1回のスクロールアニメーションが完了するまで連続発火させない場合は「not(‘:animated’)」メソッド、スクロールアニメーション中でも連続発火させて途中で次の位置へのスクロールに移行させる場合は「stop()」メソッドを使う。
- ブラウザによってscrollTopが動作している要素が違うので、「’html, body’」の両方を指定して「animate()」メソッドを実行する。厳密にどちらかの要素だけで実行させる場合は、ユーザーエージェントを調べてそれぞれに「’html’」か「’body’」を振り分ける。(ブラウザの仕様が変わる可能性があるので両方指定しておくのが無難。)
- hrefの属性値に「#」の部分(フラグメント識別子)だけでなくフルパスが指定されている場合は、jQueryの「attr()」メソッドではなくネイティブJavaScriptでprototypeオブジェクトから継承しているプロパティーのhashで参照する。
※ jQueryのeasingプラグインを導入すれば、使用できるイージングの種類を追加できる。
//初期値設定
let href,
duration = 1000, //スクロールアニメーションさせる時間(ミリ秒)
easing = 'swing'; //アニメーションイージング
//関数作成
const ag2anchorLink = function(t){
//クリックしたa要素のhrefの値を取得
href = $(t).attr('href');
//hrefの値が「#」一文字だけ、または指定のidがDOMに存在しない場合はfalseを返して終了
if(href === '#' || !$(href).length) return false;
//移動先のHTML要素のY座標トップを取得
let targetTop = $(href).offset().top;
//animateメソッドでスクロール移動を実行
$('html, body').stop().animate({scrollTop: targetTop}, duration, easing);
}
//クリックイベントで関数実行
//a要素のhref属性が#で始まる場合のみ実行する
$(document).on('click', 'a[href^="#"]', function(){
ag2anchorLink(this); //自身を渡して関数実行
return false; //アンカーの通常の機能を無効化
});
要素.attr(‘属性名’, ‘値’) : 指定した属性名で指定した値を要素に設定する。第2引数には配列や関数の指定もできる。第2引数が無い場合は、指定した属性名の値を取得して返す。
要素.offset() : documentの左上を基準点として要素の位置情報を取得する。プロパティーに「top」と「left」を含むオブジェクトを返す。引数にプロパティーと数値を指定して要素に位置座標を設定することもできる。
要素.stop(‘キューのクリア’, ‘現アニメーションの対応動作’) : 現在実行中のアニメーションを中止する。第1引数(初期値:false)がtrueなら待機中のキューを削除する。第2引数(初期値:false)がfalseの場合は現在のアニメーションは途中の状態で終了、trueの場合は即座にアニメーションの最後の状態に移動。
要素.animate(‘CSSのキーと値のマップ値’, ‘アニメーションする時間’, ‘イージング’, ‘コールバック関数’) : 第1引数に指定したCSSの状態にアニメーション変化する。数値が設定できないCSSのプロパティーは指定できない。イージングは「swing」と「linear」のみ。
[属性名^=”文字列”] : 指定した属性の値が指定した文字列から始まる要素を取得するCSSの属性セレクター。
header部分がfixedで固定デザインの場合に位置の補正
header要素を「position: fixed; top: 0;」で固定にしているデザインの場合は、そのままだと移動先がヘッダーの下に隠れるので、ヘッダーの高さ分だけスクロール位置を補正させる。
移動先の要素のY座標トップよりもヘッダーの高さ分だけ手前にしたY座標を移動先に指定する。
デザイン仕様によってheader要素の高さの設定が違うので、高さを取得するjQueryのメソッドを使い分ける。
- innerHeight() : 指定した要素のpaddingを含めた高さを返す。
- outerHeight() : 指定した要素のpaddingとborderを含めた高さを返す。
- outerHeight(true) : 指定した要素のpaddingとborderとmarginを含めた高さを返す。
let href,
duration = 1000,
easing = 'swing';
const ag2anchorLink = function(t){
href = $(t).attr('href');
if(href === '#' || !$(href).length) return false;
let targetTop = $(href).offset().top - $('header').outerHeight();
$('html, body').stop().animate({scrollTop: targetTop}, duration, easing);
};
$(document).on('click', 'a[href^="#"]', function(){
ag2anchorLink(this);
return false;
});
https://memo.ag2works.tokyo/post-1533/
(jQuery版) ページ内リンクをクリックでスクロール移動。 | memo メモ [AG2WORKS]
<a href="https://memo.ag2works.tokyo/post-1533/" target="_blank" rel="noopener">(jQuery版) ページ内リンクをクリックでスクロール移動。 | memo メモ [AG2WORKS]</a>
この記事へのコメント
コメントの書き込みはまだありません。