jQuery

jQueryで複数の要素を個別にフェードイン・フェードアウト 表示要素が共存しないタイプ【jQuery】

jQueryで複数の要素を個別にフェードイン・フェードアウトの概要

注意 ※バージョンや環境によっては正常に動作しない可能性があります。

トリガーを押すと表示されるのは変わりませんが、表示できる要素は1つだけのフェードイン・フェードアウトです。

トリガーを押す動作がされたときに、fadeToggleで要素のフェードイン・フェードアウトをするのと同時に、他の要素をfadeOutさせています。

このソースは長くなるので、改良版として、html側でdata属性をつけるのと、fadeOutをforとifで記述することで、コードを短くしていますが、for・if部分は他にいい方法ないかな~と考え中です。

最初に勉強した言語がC言語だったのですが、その際に学んだアルゴリズムなどはfor・ifが多かったので、その時の影響なのかすぐにfor・ifで書きたくなってしまいます。

動作サンプル

トリガーlong-trigger-1

トリガーlong-trigger-2

トリガーlong-trigger-3

中身long-element-1

中身long-element-2

中身long-element-3

何も表示していない状態でどれかのトリガーを押すと、表示される。

何かが表示されている時に、別のトリガーを押すと、表示されているものが消えて、押した要素が表示される。

ソースコード

HTML

<div class="long-trigger1">
  <p>トリガーlong-element-1</p>
</div>
<div class="long-trigger2">
  <p>トリガーlong-element-2</p>
</div>
<div class="long-trigger3">
  <p>トリガーlong-element-3</p>
</div>

<div class="long-element-1">
  <p>中身long-element-1</p>
</div>
<div class="long-element-2">
  <p>中身long-element-2</p>
</div>
<div class="long-element-3">
  <p>中身long-element-3</p>
</div>

css

.long-element-1, .long-element-2, .long-element-3{
    display:none;
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.125);
    border-radius: 0.25rem;
    padding: .5rem;
    margin-top: .5rem;
}
.long-trigger1, .long-trigger2, .long-trigger3{
    background-color: #bdffc6;
  }

jQuery

$(function() {
  $('.long-trigger1').click(function() {
    $('.long-element-1').stop().fadeToggle(1000);
    $('.long-element-2').stop().fadeOut(0);
    $('.long-element-3').stop().fadeOut(0);
  });
  $('.long-trigger2').click(function() {
    $('.long-element-2').stop().fadeToggle(1000);
    $('.long-element-1').stop().fadeOut(0);
    $('.long-element-3').stop().fadeOut(0);
  });
  $('.long-trigger3').click(function() {
    $('.long-element-3').stop().fadeToggle(1000);
    $('.long-element-1').stop().fadeOut(0);
    $('.long-element-2').stop().fadeOut(0);
  });
});

ソースコードの説明

HTMLでは各トリガーと各表示要素が紐づくようにクラスを設定しています。

トリガー1がクリックされると、要素1が動くというように、トリガーと中身が紐づくようなjQuerで設定をしてます。

要素は1つだけ出したいので、トリガー1がクリックされたときに、要素2か要素3が表示されている場合は、時間0でフェードアウトする設定を追加しています。

トリガー2、トリガー3も同じ設定をしているので、コードとしては長くなります。

表示の要素に対してのトリガークリック時に他の要素に対しては消える

改良版では、data属性を使用することにより、トリガーに使うクラスを1つにし、各要素に連番の数字をつけることで、forとifでコードを短くしています。

改良版動作サンプル

トリガーelement-1

トリガーelement-2

トリガーelement-3

中身element-1

中身element-2

中身element-3

動作は元のものと同じ。

改良版ソースコード

HTML

<div class="trigger" data-target="element-1">
  <p>トリガーelement-1</p>
</div>
<div class="trigger" data-target="element-2">
  <p>トリガーelement-2</p>
</div>
<div class="trigger" data-target="element-3">
  <p>トリガーelement-3</p>
</div>

<div class="element-1">
  <p>中身element-1</p>
</div>
<div class="element-2">
  <p>中身element-2</p>
</div>
<div class="element-3">
  <p>中身element-3</p>
</div>

css

.element-1, .element-2, .element-3{
    display:none;
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.125);
    border-radius: 0.25rem;
    padding: .5rem;
    margin-top: .5rem;
}
.trigger{
    background-color: #bdffc6;
  }

jQuery

$(function(){
  $(".trigger").click(function () {
    var targetName = '.' + $(this).data('target');
    $(targetName).stop().fadeToggle(1000);
    for(var i=1; i<4; i++){
      var hantei = '.element-' + i;
      if(hantei != targetName){
        $(hantei).stop().fadeOut(0);
      }
    }
  });
});

ソースコードの説明

data属性についは、下の記事をご確認ください。こちらと全く同じです。

jQueryで複数の要素を個別にフェードイン・フェードアウト 表示要素が共存するタイプ【jQuery】
jQueryで複数の要素を個別にフェードイン・フェードアウトの概要 注意 ※バージョンや環境によっては正常に動作しない可能性があります。 下の記事で、fadeToggleを使ってフェードイン・フェードアウトをする動作を記載しまし...

トリガーには全て同一のクラスを指定し、data属性でユニーク化しています。data属性をそのまま要素のクラスとして指定し、fadeToggleを動作させています。

その後のfadeOutの設定は、forとifで短縮しています。

プログラミングではお馴染みの変数iを使用したループです。

iの初期値は1で(var i=1)、ループごとにiは1ずつ増えて(i++)、ループは4未満まで(iが1、2、3の時の3回で処理が行われる)という設定をしています。

要素はelment-の後に数字で3つ作ってありますが、ループ時に文字列でその3つを作っています。「elemnet-」にforでループするiの数字をくっつけて、変数に代入しています。

そのクラスに対してfadeOutの処理が行われる形です。

そのままループさせると、クリックして表示したい要素まで消えてしまいます。なので、ループの中で表示させたい要素以外にfadeOutが動作するように、if分で判定を入れています。

表示したい要素は、クリック時に取得した要素のクラス名で判定できるので、それ以外のクラス名が来た時には、fadeOutするように「!=」で条件式を書いてあります。

今回トリガー3つに要素3つなので、ループが3回で終わるようになっていますが、iの数字を変えれば他の数でも対応できます。

3つぐらいならばコードの量にそんなに差はないですが、同時に10個とかになると、元のコードだと冗長です。forとifで書くことで、短くすることができます。

コードが短くなる分、可読性があがりメンテナンスが楽になります。ただ欠点としては、コードになれていない人にとっては、ぱっと見では何をしているコードなのかわからなくなるところです。

Webサイトの場合、フロントエンドエンジニアの方ならばjQueryは常識かもですが、HTMLとCSSだけを書くコーダーさんとか、デザイナーよりのコーダーさんだと、JavaScriptのスキルはあんまり…ということもあるため、わかりやすい記述にしていおいた方が安全、ということもたまにあります。

トリガーとボタンの数が少なければ、見やすさを重視しても良いのかな~とは思います。

まとめ

対にする要素に名前を付ける時、数字で連番を振るのはよくあることですし、すぐに思いつくことかと思います。

その要素に対して、同じ動作をする場合は、その要素を1つ1つ上から書くのではなく、繰り返し処理で書きたくなります。

ですが、WebサイトでのjQueryとなると、なんとかforとかなしで書けないかな~と考えたくなります。個人的な思いでしかないのですが、特にweb上ではむやみに繰り返し処理をしたくない、という思いがあります。

ただ、fadeoutの判定は、if文以外で思い浮かばなかったのと連番での操作なため、単純にコードが短くなったのでforとifを採用しました。なんか他にあると良いのですが。

data属性に関しては、JavaScriptの変数指定にハイフンを使えないのですが、クラス名と変数名とでみんなどうやって名前決めてるの? みたいな感じで調べていたら、data属性ってのがある、という記事を見つけて、似たようなことをしている記事があったので、それを参考にしました。

ただ、ボタンが2つとか3つとかならば、最初に書いたコードのほうがわかりやすいですし、変数がどうこうみたいなことを考えなくて良いので、デザイナーよりのweb担当者でも管理しやすいのかな~と思ったりします。

コードを書く側としては、短くて単純なほうが良いのですが、現実世界の様々な条件の中に当てはめると、一概にこっちが良い、とは言えないので、その時々の環境に合わせて選択するのが良いのかな、と思います。

タイトルとURLをコピーしました