今開いているページと同じメニュー項目の色を変える方法(javascriptで簡単実装)
開いているページと同じメニュー部分に違う色やスタイルをつける事で、今どのページを見ているのかがユーザーに認識されやすくなります。
基本はjavascriptで対象のタグ部分を配列で格納し、繰り返し処理の中でhref属性とaタグ内のリンクが一致するものを定する仕組みです。
class名を追加する際はDOM上の書き換えであり、HTMLソース上に直接入れないため共通メニューとして使い回せます。
開いているページURLと同じメニュー項目のデザインを変更する
本記事では、WEBページのナビゲーションで現在開いているページのメニュー部分の「色」を変える方法を紹介します。
メニューの1つに他と違う色・スタイルがついていれば、ユーザーに「今そのページを開いている」と認識してもらいやすくなります。
手作業はナンセンス
CSSで一つだけ別のスタイルにするのは簡単ですが、全ページそれぞれでやろうとすると大変ですよね。
手作りHTML等だと、index.htmlならindexのメニューの所、contact.htmlならcontactのメニューの所にクラス名を入れる必要があり、共通メニューとして使い回す事ができなくなる訳です。
これが実装できれば、各ページごとに個別のクラス名を入れずに済むので大変便利です。
今回は、JSコードのみで実現するパターンとJqueryを利用するパターンとを紹介します。
手元の環境に近い方を選んで実装してみてはいかがでしょうか。
javascriptで判定しクラスを追加
仕組みとしては、開いているページの「URL部分」と各ナビゲーションの「a href=""」内が一致するかを判定します。
一致した場合に、指定箇所にクラス名を追加する形です。
HTMLソース上に直接タグ追加している訳ではなく、DOMで一時的に書き換えしている事になりますね。
付与したクラス名のCSSスタイルが適用され、そこだけ色が変わる訳です。
JSコードのみで実現する方法
まずはJSコードのみで実現させる方法です。
非常に簡単に実装できるので、こちらの方がお勧めでしょう。
各構成要素
それぞれメニュー部分のHTML・メニューに適用するCSS・JSコードを準備してきます。
HTML
以下がナビゲーションメニューのソースコード例です。
<nav> <ul> <li><a class="nav-link" href="index.html">Home</a></li> <li><a class="nav-link" href="about.html">About</a></li> <li><a class="nav-link" href="service.html">Service</a></li> </ul> </nav>
いたって普通の横並びメニュー(サンプルは3項目)になります。
CSS
上記のナビゲーションメニューにCSSを当てていきます。
今回のメニューの横並びは、flexで実現しています。
nav { margin: 0; padding: 0; color: #fff; text-align: center; background-color: #333; } nav ul { display: flex; list-style-type: none; justify-content: center; } nav ul li a { display: block; color: #999; padding: 20px 10px; } nav ul li a:hover { color: #fff; background-color: #ccc; transition: all 0.3s; } /*-- 付与するcurrentクラスのスタイル --*/ a.current { color: #fff; background-color: #ff5d5e; }
さらに、今回の条件にマッチするメニュー部分に対して「current」クラスを付与します。
一番下がcurrentの専用スタイルです。
JSコード
各HTMLページの下部分で、以下のjsコードを入れましょう。
<script> document.querySelectorAll('.nav-link').forEach(link => { if(link.href === window.location.href){ link.classList.add('current') } }) </script>
上記は直接記述せず、jsファイルに書いて読み込む形でも問題はありません。
JSコードの解説
まずquerySelectorAllメソッドで「nav-link」classセレクタを指定します。
これにより、ナビメニュー内の各aタグが全て対象となる訳ですね。
続けてforEachメソッド(引数link)を使って、対象のaタグを配列として格納します。
配列の各要素に対して、urlとhref内を照らし合わせる繰り返し処理を実行します。
if文による照らし合わせ
aタグのリンクと現在表示しているページのURLが一致しているかを判定します。
・link.href…aタグのリンク内容を取得
・window.location.href…アクティブページURLから「href属性」を取得
両者が一致した場合にのみ、処理を実行する訳です。
一致したaタグに対し、classListプロパティとaddメソッドを使って、class名の「current」を追加します。
これで現在表示しているページと同じaタグに、専用のスタイルを適応する事ができる訳です。
サンプル例
サンプルはiframe内の別ファイルです。
それぞれのメニューをクリックすると、項目部分がオレンジなります。
最初に開いている上記HOMEのファイル名は「index.html」です。
javascriptのDOMで、index.htmlナビメニュー内のhref="index.html"があるaタグにcurrentクラスがつきます。
それにより背景をオレンジにできている訳です。
他のページもabout.htmlに対しhref="about.html"、service.htmlに対しhref="service.html"、となっているaタグが適用対象です。
Jqueryを使って実現する方法
次はJqueryを使った方法です。
HTML
先程と同様にナビゲーションメニューを構築しましょう。
<nav id="list"> <ul> <li><a href="index.html">HOME</a></li> <li><a href="service.html">サービス内容</a></li> <li><a href="company.html">会社概要</a></li> </ul> </nav>
同じような横並びメニュー(サンプルは3項目)を構成しています。
今回はナビメニューのnavタグに対し、id属性(#list)を付けています。
CSS
ナビメニューにCSSを当てていきます。
nav { margin: 0; padding: 0; color: #fff; text-align: center; background-color: #333; } nav ul { display: flex; list-style-type: none; justify-content: center; } nav ul li a { display: block; color: #999; padding: 20px 10px; } nav ul li a:hover { color: #fff; background-color: #ccc; transition: all 0.3s; } /*-- 付与するcurrentクラスのスタイル --*/ a.current { color: #fff; background-color: #ff5d5e; }
上記は先程のCSSと全く同じものになります。今回でもこのCSSがそのまま使えます。
JSファイル
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script> <script src="highlight.js"></script>
Jqueryと専用コードの2つを、ページの一番下で読み込ませます。
上はCDNでjqueryを読み込んでいます。下は手作りした「highlight.js」ファイルです。
jsファイルはページの一番下で読み込む事
Jquery等jsファイルは全て、ページfooter一番下(/bodyの直前)で読み込む様にして下さい。
head部分で読み込むと、コンテンツよりも先にJavaScript読み込みが優先されてしまいます。
読んだ時点ではこのコードを当てる対象が見つからず、上手く動かない訳ですね。
JSコードの解説
highlight.jsには以下のコードを記述します。
href = location.href; var links = jQuery("#list ul li a"); console.log(links); links.each(function (index, value) { if (value.href == href) { jQuery("#list ul li").children("a").eq(index).addClass("current"); } });
まず最初にlocation.hrefで、href属性の値を「href」に代入しておきます。
jQuery("")内にclassを付与したいaタグまでのhtml階層を書いて、linksに代入しておきます。
今回のナビゲーションで言うと「#list ul li a」が入りますね。
.each構文で構成を配列格納・繰り返し処理
次にconsole.log(links)とし、.each構文ですべての階層構成を配列にして格納します。
location.hrefの値と、a href=""内のURLが一致するaタグを繰り返し処理で探します。
if条件にマッチするaタグにaddclassで付与
一致するものがあった場合に以下のアクションを実行します。
jQuery("")では、aタグを含まない階層を記述します。今回は#list ul liです。
そして.childrenでつなぎ対象となるaタグに対して、.addclassで(current)を追加します。
サンプル例
見た目も挙動も先程のjqueryなしサンプルと同じですね。
jqueryなしの方は、aタグにクラス名を付けて繰り返し判定の対象にしていました。
今回は親枠タグにid属性を付けて、idが付いたタグの階層を繰り返し判定の対象にしています。