JavaScriptで現在のページのメニューリンクをアクティブ表示にする


Webサイトを利用しているユーザーが現在どのページ(カテゴリ)のコンテンツを閲覧しているのかを、ナビゲーションメニューのリンクの色を変更するなどして、わかりやすくデザインしていくこともあるでしょう。
現在表示しているWebページのリンクだけスタイルをあてる(アクティブ表示)方法としては、JavaScriptのライブラリであるjQueryを使われることが多いですが、ここではjQueryを使わず、純粋なJavaScriptでナビゲーションメニュー等のリンクを現在表示しているWebページにあわせてアクティブ表示する方法をご紹介します。

ここでご紹介する方法は、ドメイン直下だけでなく下層ページにも対応した方法になります。
しかも、ほんの数行のコードで実装できます。

今後はjQueryを使わず、純粋なJavaScriptだけで実装していきたいと考えている方に参考になればと思います。

メニューリンクをアクティブ表示


今回ご紹介するサンプルでは、以下のようなよくあるナビゲーションメニューのHTML構造とします。

HTML

<nav class="header-nav">
  <ul class="header-nav__list">
    <li class="header-nav__item"><a class="nav-link" href="/">Home</a></li>
    <li class="header-nav__item"><a class="nav-link" href="/about.php">About</a></li>
    <li class="header-nav__item"><a class="nav-link" href="/service.php">Service</a></li>
    <li class="header-nav__item"><a class="nav-link" href="/service/education.php">Education</a></li>
    <li class="header-nav__item"><a class="nav-link" href="/service/edu/programming.php">Programming</a></li>
    <li class="header-nav__item header-nav__item--contact"><a class="nav-link" href="/contact.php">Contact</a></li>
  </ul>
</nav>



または以下のように、下層ページをサブメニューとして構築してもいいでしょう。

HTML

<nav class="header-nav">
  <ul class="header-nav__list">
    <li class="header-nav__item"><a class="nav-link" href="/">Home</a></li>
    <li class="header-nav__item"><a class="nav-link" href="/about.php">About</a></li>
    <li class="header-nav__item"><a class="nav-link" href="/service.php">Service</a>
      <ul class="header-nav__sublist">
        <li class="header-nav__item"><a class="nav-link" href="/service/education.php">Education</a></li>
        <li class="header-nav__item"><a class="nav-link" href="/service/edu/programming.php">Programming</a></li>
      </ul>
    </li>
    <li class="header-nav__item header-nav__item--contact"><a class="nav-link" href="/contact.php">Contact</a></li>
  </ul>
</nav>



ポイントは各リンクのaタグにCSSクラス「nav-link」を付与しておくところです。
こちらのクラス名に対してCSSでスタイルを調整したり、JavaScriptでセレクタとして利用していきます。

続いてはCSS。
ナビゲーションリンクから、CSSクラス「active」が付与されているリンクに対してスタイルを適応させるようにします。

CSS

.header-nav__item a.active {
  color: #f00;
}

続いてはJavaScript。
JavaScriptでは、querySelectorAllメソッドを使ってセレクタを指定します。今回のサンプルでの対象セレクタは、ナビゲーションメニューの各リンクのCSSクラス「nav-link」になります。複数の対象セレクタは配列オブジェクトとして管理され、forEachメソッドを使って配列の各要素に対して繰り返し処理を実行します。
引数は「link」とします。

以下、サンプルコードになります。

JavaScript

document.querySelectorAll('.nav-link').forEach(link => {
  if(link.href === window.location.href){
    link.classList.add('active')
  }
})



JavaScriptの処理では、if文でaタグのリンクと現在表示しているページのURLが一致しているかで処理を行なっていきます。
link.hrefではaタグのhref属性が取得でき、window.location.hrefでは現在表示しているページのURLの構成要素からhref属性を取得できます。
forEachの繰り返し処理の中で、link.hrefとwindow.location.hrefのURLが一致していたら、classListプロパティaddメソッドを使って、一致しているaタグにCSSクラス「active」を追加します。

これで現在表示しているページに合わせて、ナビゲーションリンクにスタイルを適応させることができるようになります。

以下、ここまでの実装の動作になります。
動画(4分30分ほど)

余談


ちなみに、先ほどご紹介した方法の他にaria-current属性を使った方法もあります。

JavaScriptにてsetAttributeメソッドで属性を追加(aria-current=’page’)して、CSSでリンクの属性に対してスタイルを適応させるといった流れです。

CSS

.nav-link[aria-current='page'] {
  color: #f00;
}


JavaScript

document.querySelectorAll('.nav-link').forEach(link => {
  if(link.href === window.location.href){
    link.setAttribute('aria-current', 'page')
  }
})



ただaria-*属性は、W3CのWAI(Web Accessibility Initiative) が定めたWAI-ARIAにより規定されているものであり、WHATWGの「HTML Living Standard」に合わせていくのであれば、前述した方法のクラスの付与で処理していくといいでしょう。

aria-current
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current

WAI-ARIA
https://www.w3.org/TR/wai-aria/

HTML Living Standard – WHATWG
https://html.spec.whatwg.org/multipage/