アコーディオンメニューでテキストを変更させる

アコーディオンメニューでテキストを変更させる

アコーディオンって音いいですよね。
この前結構近い距離でライブ見たんですが、音が良すぎて、違う世界にいきそうでした。
音圧が全然違いました。あとあの独特の波感。

今回はWeb制作におけるアコーディオンメニューについてです。
メニューの実装の際に、割とよく使用すると思います。

アコーディオンメニューが開いたときと閉じたときにそれぞれのテキストを変更させる

ボタンに画像を使用しているとCSSスプライトが使えますが、テキストにしている場合はもちろん使えないので、jQueryを使用して動的に変えちゃいましょう。スマートフォンで使用するのが多いかもしれません。

HTMLは下記です。
「btn」を押すと「contents」がスライドするようにします。
それに加えてアコーディオンメニューが開いたときに「btn」内のテキストを「CLOSE」にしたいと思います。

HTML

<a href="" class="btn">MORE</a>
<div class="contents">contentstext</div>

普通のアコーディオンメニュー

/* !accordion --------------------------------------------------- */
$(function() {
  var $accBtn = $('.btn'),
      $accContents = $('.contents');
  
  $accContents.hide(); //contentsを全て隠す
  $accBtn.each(function() {
    $(this).click(function(e) {
      e.preventDefault(); //aタグのリンク無効化
      $(this).next().slideToggle(); //すぐ次の要素をスライド
    });
  });
});

説明

「.hide();」はスライドされる要素にCSSで「display:none;」をかけることでも併用がききますが、注意点があります。
もしJavaScriptがオフになっていたら(ほとんど無いと思いますが)、スライドされる要素がずっと非表示になってしまいます。ここはJavaScriptでコントロールした方が良いかもしれません。
「.each(function() {});」ではそれぞれのボタンに対してイベントを設定します。
「.preventDefault();」ではaタグのリンクを無効化しています。
設定しないとクリックしても普通のリンクとして機能します。
それぞれのボタンがクリックされたら、すぐ次の要素がスライドダウンします。
「.next()」は次の要素、もし前の要素にしたかったら「.prev()」を使用しましょう。

テキストを変更させるアコーディオンメニュー

/* !accordion flag --------------------------------------------------- */
$(function() {
  var $accBtn = $('.btn'),
      $accContents = $('.contents');
  
  $accContents.hide(); //contentsを全て隠す
  $accBtn.each(function() {
    var flag = "close"; //flagを初期値を設定
    $(this).click(function(e) {
      e.preventDefault(); //aタグのリンク無効化
      $(this).next().slideToggle(); //すぐ次の要素をスライド

      if(flag == "close"){ //もしflagがcloseだったら
        $(this).text("CLOSE");
        flag = "open"; //flagをopenにする
      }
      else{ //もしflagがopenだったら
        $(this).text("MORE");
        flag = "close"; //flagをcloseにする
      }

    });
  });
});

説明

普通のアコーディオンメニュー + 変数「flag」の値に対して条件分岐を使ってテキストの表示を変更します。

「flag」が「close」だったら スライド(開く)
テキストを「CLOSE」に変更
「flag」の値を「open」に変える
「flag」が「open」だったら スライド(閉じる)
テキストを「MORE」に変更
「flag」の値を「close」に変える

という処理が行われます。

もし画像スプライトを使いたかったら

あくまでも一例です。

/* !accordion sprite --------------------------------------------------- */
$(function() {
  var $accBtn = $('.btn'),
      $accContents = $('.contents');
  
  $accContents.hide(); //contentsを全て隠す
  $accBtn.each(function() {
    $(this).click(function(e) {
      e.preventDefault(); //aタグのリンク無効化
      $(this).toggleClass('is-active').next().slideToggle(); //クラスを追加してすぐ次の要素をスライド
    });
  });
});
.btn{
  display: block;
  width: 100px;
  height: 50px;
  background: url("../images/btn.png")no-repeat 0 0;
}
.btn.is-active{
  background-position: 0 -50px;
}

説明

ここでは「.toggleClass()」を使用して「btn」に対してクラスの付け替えを行います。
クリックされる(スライドが開くと)「is-active」というクラスが付きます。
その場合に「background-position」を変更してあげるとCSSスプライトによる実装が可能です。

使うときの条件

上記で作ったアコーディオンメニューは下記の条件で使うことを仮定しています。

  • ボタンをaタグにする
  • アコーディオンメニューが複数ある

もしボタンにpタグ等を使った場合は

「e.preventDefault();」は不要になります。
その際、ボタンにCSS「cursor:pointer;」をかけてあげるとマウスオンでカーソルが変わるので親切です。

//$(this).click(function(e) { //eも不要
$(this).click(function() {
  //e.preventDefault(); //不要
  $(this).next().slideToggle(); //すぐ次の要素をスライド
});

アコーディオンメニューが一つしかない場合

「$accBtn.each(function() {});」は不要になります。

//$accBtn.each(function() { //不要
  //$(this).click(function(e) { //置き換える
  $accBtn.click(function(e) {
    e.preventDefault(); //aタグのリンク無効化
    $(this).next().slideToggle(); //すぐ次の要素をスライド
  });
//}); //不要

デモ

デモを用意しました。

DEMO

  • 普通のアコーディオンメニュー
  • テキストを変更させるアコーディオンメニュー
  • 画像スプライトのアコーディオンメニュー
  • アイコンが回転するアコーディオンメニュー

4種類を作りました。
レスポンシブで使えます。
アイコンは疑似要素で作成しています。

さいごに

結構使えるところはあるかと思います。
上記のアコーディオンはあくまでも例なので、使い方によって変更していって下さい。