タブ切り替えなどを実現するJavaScript

はじめに

当サイトのトップブログセクションのタグをクリックするとそのタグの記事のみが表示されます(本記事執筆時点)

例えば技術ブログの「#HTML/CSS」をクリックすると、HTML/CSSというタグを持つ記事のみが表示されます。

こんな感じで何かの要素をクリックしたときに、対象の要素の表示・非表示が切り替わる仕組みをJavaScriptで実現するにはどうすればいいのかについて書いていきます。

まずは要素を取得して変数に入れる

トリガー(きっかけ)となる要素と表示・非表示を切り替えたい要素の2つを取得して変数に入れます。

今回の例では前者がタグ、後者が記事となります。

トリガー(きっかけ)となる要素

今回の例では、top-skill-blog__tag-liというクラス名を持ったli要素です。

タグをクリックした時に記事の切り替えを行いたいため、こちらがトリガーとなります。

以下のようにして、タグの要素すべての情報を取得したもの(右辺)を、skill_tagという変数(左辺)に入れました。

const skill_tag = document.querySelectorAll(".top-skill-blog__tag-li");

表示・非表示を切り替えたい要素

今回の例では、blog-list-scroll__link–skill-blogというクラス名を持ったdiv要素です。複数クラスがついていて.(ドット)で繋がれています。

以下のようにして、記事を全て取得したもの(右辺)を、skill_articleという変数(左辺)に入れました。

const skill_article = document.querySelectorAll(".blog-list-scroll__link--skill-blog");

関数の定義・実行

定義

今回は、タグをクリックした時の動きについての処理を書きたいので、tag_motionという名前の関数を作成しました。

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

実行

実行するときは以下のように書きました。

tag_motion(skill_tag, skill_article);

第一引数として渡しているskill_tagはタグを全て取得したもので、第二引数のskill_articleは記事を全て取得したものです。

関数の解説①: タグに対する処理

タグに関する処理について解説していきます。

forEach文で一つ一つに対して処理を行う

tag_motion関数の中ではskill_tagをtag_listとして使用し、forEach文の中で、tagとして一つ一つに対した処理を書いていきます。

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

forEach文の中ではtagに対してクリックイベントを設定しています。タグをクリックした時にこの中に書いた処理が行われます。

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

タグについているactiveを削除する関数

タグをクリックした時に全てのタグについているactiveというクラスを取り除くtag_all_reset関数が実行されます。

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

tag_all_resetは以下のように定義した関数です。

function tag_all_reset(tag_list) {
  tag_list.forEach(function (tag) {
    tag.classList.remove("active");
  });
}

タグそれぞれについているactiveというクラスを削除するという処理です。

タグにactiveがついていると以下のように色が反転するようにしています。

CSSで以下のような記述をしています。少し滑らかに変化させるためにtransitionを設定しました。

.top-skill-blog__tag-li.active {
    transition: all 0.3s;
    background-color: #0a2c54;
    color: #fff;
}

このactiveを最初に取り除いてフラットな状態にしておきます。

クリックしたタグ要素にactiveというクラスを付ける

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

クリックしたtagにactiveというクラスを追加することで、そのタグの色が反転するようにしました。GitHubというタグをクリックした場合は以下のようになります。

関数の解説②: 記事に対する処理

次に記事それぞれに対しての処理が行われます。

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

タグについている属性を取得する

tag.getAttribute(“tagslug”)でtagslugという属性の値を取得し、tagslugに代入します。

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

例えば、GitHubというタグについて見ていきます。

tagには以下のようにtagslugという属性をつけていました。

<li class="top-skill-blog__tag-li" tagslug="github">#GitHub</li>

上記は、WordPressのテンプレートファイルに書いたPHPで、それぞれのタグのスラッグが出力されるようにして、そのHTMLが出力された結果です。

その部分を抜き出すと以下のようになります。

echo '<li class="top-' . $cat_slug . '__tag-li" tagslug="' . $tag->slug . '">#' . $tag->name . '</li>';

GitHubのタグをクリックした場合、tag.getAttribute(“tagslug”)でgithubという値を取得し、tagslugに代入されます。

記事の要素それぞれに対して処理を行う

次にforEach文を使用してarticleに対して処理を行っていきます。このarticleは記事一つ一つのことです。

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

まずは全ての記事を表示させる

notShowMeというクラスを記事から取り除きます。

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

notShowMeが付くと非表示になるようにCSSで設定してあります。

.notShowMe {
    display: none;
}

そのため、notShowMeが取り除かれると記事が表示されます。

次にクリックしたタグではない記事を非表示にする

function tag_motion(tag_list, article_list) {
  tag_list.forEach(function (tag) {
    tag.addEventListener("click", function () {
      tag_all_reset(tag_list);
      tag.classList.add("active");
      tagslug = tag.getAttribute("tagslug");
      article_list.forEach(function (article) {
        article.classList.remove("notShowMe");
        if (!article.classList.contains(tagslug)) {
          article.classList.add("notShowMe");
        }
      });
    });
  });
}

if文の条件である !article.classList.contains(tagslug) は、記事にクリックしたタグのtagslug属性の値が含まれていないという条件です。

その場合に、記事にnotShowMeが付きます。そして記事が非表示になります。

記事には以下のようにしてタグのスラッグがクラスに表示されるように仕込んでおきました。

<a class="<?php echo $tag->slug; ?> blog-list-scroll__link blog-list-scroll__link--<?php echo $cat_slug; ?>" href="<?php the_permalink(); ?>">

クラスにクリックしたタグのスラッグがある場合は、非表示になりません。そのため、クリックしたタグの記事のみが残ります。

コメントを残す

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