Intersection Observer を使ったアンカーリンクナビ

Intersection Observer を使ったアンカーリンクナビ

交差監視を利用したアンカーリンクナビゲーション

#196 アンカーリンクナビ

WEB制作

JavaScriptの交差監視「Intersection Observer」を使って、アクティブな要素の時にナビゲーションが変化するアンカーリンクナビを作りました。 サイト内のページ導線につかえるナビゲーションです。

公開日:
最終更新日:

サイトマップサイトマップ

Intersection Observer を使ったアンカーリンクナビ

Intersection Observerを使ったアンカーリンクのナビゲーションを作ってみました。
要素の位置に応じて、ナビゲーションのマーカーが表示される仕組みです。

インターセクションオブザーバーについての解説記事はこちら

サンプルの内容が思いつかなかったのでオススメのPC周りのグッズを紹介しておきます。

WEBカメラ C920n とUSB切替器

c920n

ロジクールのWEBカメラC920nを2台のPCで共有するためにUSBスイッチャーを導入した記事です。

USBスイッチャーがあるおかげでUSBの付け替えが不要で楽ちんです。

ロジクールの高機能高級ワイヤレスキーボード CRAFT

ロジクールの高機能高級ワイヤレスキーボード CRAFT

ロジクールが出している高級ワイヤレスキーボードCRAFT(KX1000s)。キーストロークが浅めが好みの私にはドンピシャのお気に入りキーボードになりました。

これも2台のPCをボタン1つで切り替えて、共通して使える優れモノ。

フットレストで腰への負担を軽減しよう

フットレストで腰への負担を軽減しよう

イスに座った状態で足を伸ばすと、地面に接地する距離が少し遠く、太ももや腰に負担がかかるのでフットレストを導入しました。

あぐら姿勢で仕事することが多かったのですが、フットレストを導入してから少し姿勢が良くなった気がします。

HUAWEI ウルトラワイドモニター MateView GT

HUAWEI ウルトラワイドモニター MateView GT

でかいモニターに慣れるともう小さいモニターでは仕事する気になれません。1画面で得られる情報量は多い方が色々楽です。

ワイドモニターに縦置きのモニターがあれば、完璧な作業環境が手に入ります。

サイト内のアンカーリンクナビをCSSのstickyで固定して、クリックするとアンカーリンクで移動する仕組みです。

要素に入ったらナビゲーションのラインアニメーションを発動

今回のサンプルはスクロールに応じて、アンカーリンクのナビゲーションのラインが表示されるという仕組みです。

スクロール監視ということで「Intersection Observer」を利用した仕組みになっています。

ナビゲーション部のHTMLソース

ナビゲーションは普通に作られています。

<ul id="unker_nav">
	<li><a href="#pos1">オススメ1</a></li>
	<li><a href="#pos2">オススメ2</a></li>
	<li><a href="#pos3">オススメ3</a></li>
	<li><a href="#pos4">オススメ4</a></li>
</ul>

監視ターゲットのHTMLソース

こちらは監視要素を共通のクラス「inter_pos」を設定し、data属性を使ってナンバリングをしています。
ナビゲーションのインデックス番号とリンクさせるためのナンバリングです。

<div id="pos1" class="inter_pos" data-num="0">
<h3>pos1</h3>
</div>
		
<div id="pos2" class="inter_pos" data-num="1">
<h3>pos2</h3>
</div>

<div id="pos3" class="inter_pos" data-num="2">
<h3>pos3</h3>
</div>

<div id="pos4" class="inter_pos" data-num="3">
<h3>pos4</h3>
</div>

実際のサンプルソースとは異なりますが、説明に不要な個所は省いています。

Intersection Observerを設定しているJavaScript

インターセクションオブザーバーのスタンダードな使い方になっていますが、今回は監視対象と、クラスを付与する要素が異なります。

交差した要素のdata-numに振られた数値を取得し、その数値をliのインデックスとして利用し、そのliにクラスを付与&削除する仕組みです。

//▼監視対象
const target_item = document.querySelectorAll(".inter_pos");

//▼ナビゲーションのliを取得
const unker_nav = document.querySelectorAll("#unker_nav li");	
	
window.addEventListener("load", (event) => {
	let vh = document.documentElement.clientHeight;
	let nav_vh = document.getElementById('unker_nav').clientHeight;
	let head_vh = document.getElementById('header_box').clientHeight;
	let fix_vh = nav_vh + head_vh + 20;
	var zan_vh = vh - fix_vh;	
	createObserver(zan_vh, fix_vh);	
}, false);

function createObserver(zan_vh, fix_vh) {	
	let options = {
		root: null,
		rootMargin: "-" + fix_vh + "px 0px  -" + zan_vh + "px 0px",				
		threshold: 0
	};
	let main_observer;
	main_observer = new IntersectionObserver(nav_set, options);
	target_item.forEach( (elem) => {
		main_observer.observe(elem);
	});  
}	

function nav_set(entries){	
	entries.forEach(entry => {
		//▼data-numの取得
		let set_num = entry.target.dataset.num
		if (entry.isIntersecting) {
			//▼取得したdata-numを使ってアクティブなliにクラス付与
			unker_nav[set_num].classList.add("sample_on");			
		}else{
			//▼交差範囲から外れたらクラスを外す
			unker_nav[set_num].classList.remove("sample_on");			
		}				
	});
}

ナビの当たり判定を可能な限り正確にしたくて、ごちゃごちゃと色々やってます。
11行目~16行目です。

JavaScriptで各要素の高さを取得して、計算して出しています。

適切なrootMarginの求め方

rootMarginの調整で、交差範囲をアンカーナビのところに持ってくるのに苦労しました。
色々と試行錯誤してこの形になりました。

ターゲットはli
rootMarginの求め方

最初はざっくりと-80%とかで設定していたんですが、ウィンドウサイズを変更すると交差範囲がずれるのが気に入らなくて、なるたけ厳密に求めるようにしました。
これが正しいかどうかは不明ですが、とりあえず納得できる動きになりました。

JavaScriptを使ってそれぞれの要素の高さを取得し、関数の引数にあてて適用してます。

もっとちゃんとやるとしたら、閲覧中にウィンドウサイズが変更された際に、全ての高さを再取得する必要があります。
そこまではいいかなと思ってやってません。

CSSアニメーションで動きをつける

メインのJavaScriptの解説は終わったので、CSSを簡単に紹介して終わりたいと思います。

#unker_nav {
	display: flex;	
	width: 100%;
	justify-content: space-between;
	position: sticky;
	z-index: 1;
	top: 70px;
	background: rgba(0,0,0,0.8);
	padding-bottom: 4px;	
}
	
#unker_nav li{
	width: 24.5%;
	text-align: center;	
	transition: all 0.3s 0s ease;	
}
	
#unker_nav li a{
	display: block;
	padding: 4px 0;
	color: #fff;
	box-sizing: border-box;
}

#unker_nav li:hover{
	background: #000;
	opacity: 0.8;
}

.sample_on{
	background: #000;
	position: relative;
}	

.sample_on::after {
	content: '';
	position: absolute;
	left: 0;
	bottom: 0;
	border-bottom: solid 3px #c00;
	animation: border_anim 0.2s ease-in forwards;
}

@keyframes border_anim { 
	0% { width: 0%; }
	30% { width: 50%; }
	100% { width: 100%; } 
}

@media screen and (max-width: 640px){
	#unker_nav {
		top:41.5px;
	}
}	

#unker_navを 「postion: sticky;」 で固定しています。

44行目の「@keyframes border_anim」でアニメーション効果を作って、交差した時にラインアニメーションを適用しています。

その他は主にレイアウトのCSSですね。
※関係なスタイルは省いています。

Intersection Observer を使ったアンカーリンクナビ まとめ

今回のナビゲーションも前回に引き続き、仕事で使ったんですが、交差範囲の設定が甘くてもうちょっと完成度を高めたかったのですが、納期の都合で許容範囲までしか詰め切れず。

というわけで、インターセクションオブザーバーの使用例も兼ねて、研究してみました。

アンカーナビのアニメーションとアクティブ判定がいらなければ、交差監視は不要です。
だけど、ちょっとした遊び心とユーザビリティを加えたくなるじゃないですか。

こういう売上や成果に直結するとは言い難い、パーツや動き、仕組みなんかをどれだけ持っているかを私は結構大事にしています。

仕事で詰め切れないことを自分のサイトで突き詰めて、次に仕事に生かすと。

またインターセクションオブザーバーを使って、なにかを作りたいとおもいます!

WEBデザイナー・プログラミング学習にオススメ

記事内で紹介している商品リスト
(価格はAmazon参考価格)

ステップアップJavaScript フロントエンド開発の初級から中級へ進むために

2,376円(税込)

ステップアップJavaScript フロントエンド開発の初級から中級へ進むために

独習JavaScript 新版

2,950円(税込)

独習JavaScript 新版

JavaScript 第7版

5,060円(税込)

JavaScript 第7版

いちばんやさしいJavaScriptの教本 第2版 ECMAScript 2017(ES8)対応 人気講師が教えるWebプログラミング入門 「いちばんやさしい教本」シリーズ

2,178円(税込)

いちばんやさしいJavaScriptの教本 第2版 ECMAScript 2017(ES8)対応 人気講師が教えるWebプログラミング入門 「いちばんやさしい教本」シリーズ

図解! JavaScriptのツボとコツがゼッタイにわかる本 “超”入門編

2,138円(税込)

図解! JavaScriptのツボとコツがゼッタイにわかる本 “超”入門編

JavaScript コードレシピ集

3,114円(税込)

JavaScript コードレシピ集

JavaScript[完全]入門

2,653円(税込)

JavaScript[完全]入門

アンカーリンクナビの関連ページ

SNSでこの記事をシェアできます

ブログ デイリーアクセスランキング

車用スマホホルダー
1位

車用スマホホルダー

スマホをカーナビとして使うと熱さで充電ができなくなるので、熱対策と1年間使って外れることがなかったスマホホルダーの紹介。

ノートPCスタンド
2位

ノートPCスタンド

ノートパソコンを横にしまうと結構な専有面積があるのですが、立てて収納できればわずか数cmで使えるので本当に快適です!

SVG背景
3位

SVG背景

SVG背景を覚えたらborderで背景画像を作るのが馬鹿らしくなります。 それくらい簡単で汎用性の高い方法です。

MusicBeeのレイアウト変更方法
4位

MusicBeeのレイアウト変更方法

MusicBee 3.1のレイアウトをデフォルトの状態から、自分好みのレイアウト設定に変更する方法を写真付きで紹介しています。

GA4カスタムイベント
5位

GA4カスタムイベント

GA4のカスタムイベントをGTMを使い設定する方法です。 イベント、パラメータ、カスタムディメンションの解説記事です。

アンカーリンクナビ
6位

アンカーリンクナビ

JavaScriptの「Intersection Observer」を使い、ナビゲーションが変化するアンカーリンクを作りました。

PHPで作るカレンダー
7位

PHPで作るカレンダー

forとifとforeachがメインのPHPによるカレンダーの作り方です。 祝日設定がちょっとめんどくさいんですよね。

音楽再生
8位

音楽再生

パソコンに取り込んだ音楽をせっかくならCDコンポから再生したいと思ったことありませんか?AUXを使った外部接続の方法の紹介です。

ロリポップサーバー設定
9位

ロリポップサーバー設定

ロリポップサーバーのアクセラレーターの設定方法やPHPのバージョン変更などの簡単にできるサーバ設定5つを解説!

MusiceBee
10位

MusiceBee

PCで音楽の再生と管理をするならiTunseよりもMusicBeeがオススメです。軽くて早くて便利で使いやすい。

カテゴリ一覧

オススメ商品レビュー

オススメ商品レビュー

世の中にある比較サイトや、いかがでしたか系サイトが嫌いなんです。使ってないのにえらそうなこと言うなと。なので体験談です。

WEB制作

WEB制作

WEBサイトを作れますと一言に言っても色々な技術があるわけですよ。アウトプットの形は一緒でもいろいろこだわりがあるんです。

カメラ

カメラ

2018年4月に購入したソニーのミラーレス一眼「α7Ⅲ」に関連する記事一覧ページです。 作例集やカメラグッズレビューなど。

美味しいもの

美味しいもの

食に関してはあまりこだわりがないんですけどね、こだわりがない分美味しいと思ったものは本当においしいと思ったものなんですよ

Amazonプライム動画

Amazonプライム動画

Amazonプライム会員なら無料で利用できるAmazonプライム動画から、いろいろな動画をみたレビュー記事のまとめページ

旅LOG

旅LOG

家族旅行やおでかけした際の旅ブログです。夏休みの家族旅行(4人家族)で訪れた観光名所の感想などを記しています。

プロフィール

プロフィール

Start-Point.netの管理人のプロフィール紹介を兼ねた、自分の中のルールや決め事やエピソードなでお書いていきます

日記

日記

日記と言っても色々な日記があるわけで、記録的な日記や心理描写を色濃く描いた日記などをまとめたページです。

thanks

thanks

自分を表現することって意外と難しいんですよね。照れがあったり、間違ったこといってないかとよくわからない何かと戦ったりして。

記事内で紹介している商品

ステップアップJavaScript フロントエンド開発の初級から中級へ進むために

2,376
(税込)