ナビゲーションの現在地設定をJavaScriptで対応する

閲覧中のページURLに応じてナビゲーションにカレントのスタイルを設定する実装をメモ。

サンプルコード

今回は以下の2パターンを実装してみます。

  • 閲覧中のURLが対象のナビゲーションのディレクトリ配下の場合にスタイルを設定するパターン(ヘッダーナビなど)
  • 閲覧中のURLと一致するナビゲーションにスタイルを設定するパターン(ローカルナビなど)

まず一つ目のパターンの想定で、ヘッダーのナビを追加します。
JavaScriptでの制御用に、各ナビにjs-nav-dir-currentというclassを付与しておきます。

<header class="header">
  <nav class="nav">
    <ul class="nav-list">
      <li class="nav-item js-nav-dir-current">
        <a href="/about/">会社概要</a>
      </li>
      <li class="nav-item js-nav-dir-current">
        <a href="/service/">サービス</a>
      </li>
      <li class="nav-item js-nav-dir-current">
        <a href="/contact/">お問い合わせ</a>
      </li>
      <li class="nav-item js-nav-dir-current">
        <a href="/blog/">ブログ</a>
      </li>
    </ul>
  </nav>
</header>

二つ目のパターンの想定で、about ディレクトリ(会社概要)内にローカルナビを追加します。
先ほどと同様に、各ナビにjs-nav-path-currentという別のclassを付与しておきます。

<nav class="side-nav">
  <ul class="sidenav-list">
    <li class="sidenav-item js-nav-path-current">
      <a href="/about/index.html">会社概要</a>
    </li>
    <li class="sidenav-item js-nav-path-current">
      <a href="/about/messages.html">メッセージ</a>
    </li>
    <li class="sidenav-item js-nav-path-current">
      <a href="/about/vision/">経営理念</a>
    </li>
    <li class="sidenav-item js-nav-path-current">
      <a href="/about/vision/mission/">ミッション</a>
    </li>
    <li class="sidenav-item js-nav-path-current">
      <a href="/about/history.html">沿革</a>
    </li>
    <li class="sidenav-item js-nav-path-current">
      <a href="/about/location.html">所在地</a>
    </li>
  </ul>
</nav>

カレントの場合はis-currentというclassが付与されるようにするので、そのスタイルを用意しておきます。

.nav-item.is-current a {
	color: red;
}
.sidenav-item.is-current a {
	color: red;
}

最後にJavaScriptでの実装です。

document.addEventListener('DOMContentLoaded', () => {
  setCurrentToMatchPathNav();
  setCurrentToMatchDirNav();
});

/*
* ページURLと一致するナビゲーションにカレントを付与する
*/
function setCurrentToMatchPathNav() {
  // 調整したページURLを取得
  const pageDir = adjustPageDisplay(window.location.pathname);
  // 対象のナビゲーションのうち、ページURLと一致するものにカレントを付与する
  const navItems = document.querySelectorAll('.js-nav-path-current');
  navItems.forEach(item => {
    const itemLink = item.querySelector('a');
    if (!itemLink) return;
    const itemLinkPathname = new URL(itemLink.href).pathname;
    const itemLinkDir = adjustPageDisplay(itemLinkPathname);
    if (itemLinkDir === pageDir) {
      item.classList.add('is-current');
    }
  });
}

/*
* ページURLが対象のナビゲーションのディレクトリ配下の場合にカレントを付与する
*/
function setCurrentToMatchDirNav() {
  // 調整したページURLを取得
  const pageDir = adjustPageDisplay(window.location.pathname, false);
  // 対象のナビゲーションのうち、ページURLと先頭から途中まで一致するものにカレントを付与する
  const navItems = document.querySelectorAll('.js-nav-dir-current');
  navItems.forEach(item => {
    const itemLink = item.querySelector('a');
    if (!itemLink) return;
    const itemLinkPathname = new URL(itemLink.href).pathname;
    const itemLinkDir = adjustPageDisplay(itemLinkPathname, false);
    if (pageDir.startsWith(itemLinkDir)) {
      item.classList.add('is-current');
    }
  });
}

/*
* ページURLの調整
* @param {string} dir ページURL
* @param {boolean} filename ファイル名を含めるかどうか
* @returns {string} 調整後のページURL
*/
function adjustPageDisplay(dir, filename = true) {
  // ディレクトリの末尾にファイル名(htmlファイル)がない場合はindex.htmlを付与する
  if (filename && !dir.endsWith('.html')) {
    if (!dir.endsWith('/')) dir += '/';
    dir += 'index.html';
  }
  return dir;
}

ナビゲーションにカレントを設定するデモページ

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2025年11月
 1
2345678
9101112131415
16171819202122
23242526272829
30