「もっと見る」ボタンの実装方法|クリックで要素を表示・非表示切り替え【JavaScript】

どうも、くまだです。

ボタンをクリックしたら隠れていたアイテムを表示して、再クリックしたら非表示に戻す。ボタンのテキストも「もっと見る→閉じる→もっと見る」と連動して切り替わる、いわゆる 「もっと見る」ボタンの実装メモです。

わりとよく見かけるやつなので、それのメモです。

リストの件数によって表示・非表示のパターンが変わる場合は、こちらの記事も参考にどうぞ。

クリックしたらアイテムの表示・非表示をJavaScriptで切り替え

動きとしては以下のような感じです。(CSSは最低限の見た目のみ)

See the Pen クリックしたら要素の表示・非表示切り替え by kuma0605 (@kuma0605) on CodePen.

  • デフォルトでは10件を表示、11件目以降は非表示
  • 「もっと見る」ボタンを押すと非表示だった記事が展開される
  • ボタンのテキストが「閉じる」に変わる
  • もう一度押すと元の表示に戻り、ボタンも「もっと見る」に戻る

〇 HTML

<div class="p-list-wrap">

    <ul class="p-list js-list">
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。見出しが入ります。見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
      <li class="p-list__item c-link-item">
        <a href="">
          <h3 class="c-link-item__title">見出しが入ります。</h3>
        </a>
      </li>
    </ul>
    <div class="p-list__button">
      <button class="c-plus">
        <div class="c-plus__inner">
          <div class="c-plus__button"></div>
          <p class="c-plus__text">もっと見る</p>
        </div>
      </button>
    </div>
  </div>

ポイントは js-list クラスです。JavaScript側でこのクラスを持つ要素を取得して操作します。

〇 CSS

/* 調整用 */

ul,li {

	list-style: none;

}

a {
	text-decoration: none;
	color: #000;
}

input, textarea, select, button {
	color: inherit;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	line-height: inherit;
	*font-size: 100%;
	border-radius: 0;
	border: none;
	appearance: none;
	-webkit-appearance: none;
	background-color: inherit;
}

.c-plus {
	cursor: pointer;
}

.c-plus__inner {
	display: flex;
	align-items: center;
	justify-content: center;
}

.c-plus__button {
	display: block;
	position: relative;
	width: 40px;
	height: 40px;
	margin-right: 16px;
	border: 1px solid red;
	border-radius: 50%;
}



.c-plus__button::before {
	display: block;
	position: absolute;
	top: 50%;
	left: 50%;
	width: 13px;
	height: 1px;
	transform: translate(-50%, -50%);
	background: red;
	content: "";
}

.c-plus__button::after {
	display: block;
	position: absolute;
	top: 50%;
	left: 50%;
	width: 1px;
	height: 13px;
	transform: translate(-50%, -50%);
	background: #EA5404;
	content: "";
}

.p-list__button.is-close .c-plus__button::after{
display: none;
}

.p-list .p-list__item:nth-of-type(n + 11) {
	display: none;
}

.p-list.is-open .p-list__item:nth-of-type(n + 11) {
	display: block;
}

nth-of-type(n + 11) で「11件目以降のliすべて」を指定しています。JavaScriptでクラスを付け外しするだけで表示・非表示が切り替わる仕組みです。

〇 JavaScript

document.addEventListener('DOMContentLoaded', function () {
  const more = document.querySelector(".c-plus");
  const list = document.querySelector(".js-list");
  const el = list.nextElementSibling;

  more.addEventListener("click", function () {

    if (list.classList.contains("is-open")) {
      list.classList.remove('is-open');
      el.querySelector('.c-plus__text').textContent = 'もっと見る';
      el.classList.remove('is-close');

    } else {
      list.classList.add('is-open');
      el.querySelector('.c-plus__text').textContent = '閉じる';
      el.classList.add('is-close');
    }
  });
});

デフォルトでは記事の11件目からCSSで下記の部分で非表示にしています。

.p-list .p-list__item:nth-of-type(n + 11) {
	display: none;
}

.p-listにis-openクラスが付与されたら表示するようにこちらもCSSで調整。

.p-list.is-open .p-list__item:nth-of-type(n + 11) {
	display: block;
}

ボタンの「+」を「ー」にするのも下記の部分で調整。

.p-list__button.is-close .c-plus__button::after{
 display: none;
}

下記の部分で、ボタンと一覧部分(ul)を取得。

  const more = document.querySelector(".c-plus");
  const list = document.querySelector(".js-list");
  const el = list.nextElementSibling;

nextElementSiblingは次の要素を取得するプロパティで、js-listの次の要素がp-list__buttonにあたります。

ボタンをクリックしたらイベント発火させたいので、下記の部分に処理を書く。

more.addEventListener("click", function () {
  // ここにクリックされたときの処理を書く
});

if文でjs-list要素にis-open クラスがついてるかいないかで処理を分けます。is-openがついていたら消す、なかったらis-openをjs-listに付与。あとel(p-list__button要素)にも。

    if (list.classList.contains("is-open")) {
      list.classList.remove('is-open');
      el.querySelector('.c-plus__text').textContent = 'もっと見る';
      el.classList.remove('is-close');

    } else {
      list.classList.add('is-open');
      el.querySelector('.c-plus__text').textContent = '閉じる';
      el.classList.add('is-close');
    }

textContentは指定した要素のテキストコンテンツを取得、もしくは、設定することができるプロパティです。こちらもif文で処理を出しわけ。つまり、is-openがjs-listに付与されるのといっしょに、ボタンのテキストを「閉じる」に書き換え。

is-openが外れたら、ボタンのテキストを「もっと見る」に書き換える。

ここまで読んでくださりありがとうございました。

この記事を書いた人