【HTML,CSS】クリックしたら要素の表示・非表示切り替え【JavaScript】

どうも、くまだです。

ボタンをクリックしたら非表示になっていたアイテムを表示、再クリックしたらアイテムが非表示になり、ボタンのテキストが「もっと見る→閉じる」「閉じる→もっと見る」と切り替える際の処理。

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

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

動きとしては以下のような感じ。(CSSは適当です)

例えば記事一覧ページで、デフォルトで何件が表示されていて、ボタンを押すと隠れていた記事が表示される。そのときに、ボタンの文言が「もっと見る→閉じる」に変更。

再度クリックするとボタンのテキストが、「閉じる→もっと見る」に変更され、一覧がデフォルト表示件数に戻る、という具合です。

〇 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>

〇 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;
}

〇 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が外れたら、ボタンのテキストを「もっと見る」に書き換える。

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

この記事を書いた人