質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

  • JavaScript

    17514questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    7106questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

文字が少し違うだけの複数のイベントを1つにまとめたいです

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 231

takopo

score 123

質問させてください。
今、ボタンを押すと画像が切り替わるプログラムをjqueryで書いていまして、うまく動作はしたものの、以下のような数字が違うだけの複数のイベントをもう少しシンプルにできればなと思い、1つにまとめる方法を探してみたのですがなかなか見つかりませんでした。もし良い方法がありましたらどなたかご教授いただけないでしょうか。

$(function() {
  $('.btn1').on('click', function() {
    test(1);
  });
  $('.btn2').on('click', function() {
    test(2);
  });
  $('.btn3').on('click', function() {
    test(3);
  });
  $('.btn4').on('click', function() {
    test(4);
  });
  $('.btn5').on('click', function() {
    test(5);
  });
});

htmlは以下のような形になっております。(質問用に少し簡明にしてあります。)

<img class="btn1" src="btn.png">
<img class="btn2" src="btn.png">
<img class="btn3" src="btn.png">
<img class="btn4" src="btn.png">
<img class="btn5" src="btn.png">

実際のソースはけっこう煩雑になっているのですが以下に記載させていただきます。
実はボタンをクリックではなく、サムネイルをマウスオーバーで、拡大部に画像とテキストを表示させるようにしています。ここのイベント部分が少し重複気味だなと思い、質問させていただきました。

$(function(){
  $('.js-gallery').each(function() {
    var $_self = $(this);

    function DisplayImage(num) {
      var img_full = $_self.find('.js-change-img' + num + ' img').attr('src');
      $_self.find('.js-gallery-target img').fadeOut('fast', function() {
        $_self.find('.js-gallery-target img').attr('src', img_full).fadeIn();
        for (var i = 1; i <= 8; i++) {
          $_self.find('.js-change-txt' + i).hide();
        }
        $_self.find('.js-change-txt' + num).fadeIn();
      });
    }

    $_self.find('.js-change-img1 img').mouseover(function() {
      DisplayImage(1);
    });
    $_self.find('.js-change-img2 img').mouseover(function() {
      DisplayImage(2);
    });
    $_self.find('.js-change-img3 img').mouseover(function() {
      DisplayImage(3);
    });
    $_self.find('.js-change-img4 img').mouseover(function() {
      DisplayImage(4);
    });
    $_self.find('.js-change-img5 img').mouseover(function() {
      DisplayImage(5);
    });
    $_self.find('.js-change-img6 img').mouseover(function() {
      DisplayImage(6);
    });
    $_self.find('.js-change-img7 img').mouseover(function() {
      DisplayImage(7);
    });
    $_self.find('.js-change-img8 img').mouseover(function() {
      DisplayImage(8);
    });
  });
});
<div class="js-gallery">
  <!-- 拡大部 -->
  <div class="c-gallery__large js-gallery-target">
    <div class="c-gallery__large-img"><img src="images/common/sample/sample01.jpg" alt="" style="display: inline;"></div>

    <!-- テキスト -->
    <div class="js-change-txt1" style="display: block;">テキスト1テキスト1テキスト1テキスト1</div>
    <div class="js-change-txt2" style="display: none;">テキスト2テキスト2テキスト2テキスト2</div>
    <div class="js-change-txt3" style="display: none;">テキスト3テキスト3テキスト3テキスト3</div>
    <div class="js-change-txt4" style="display: none;">テキスト4テキスト4テキスト4テキスト4</div>
    <div class="js-change-txt5" style="display: none;">テキスト5テキスト5テキスト5テキスト5</div>
    <div class="js-change-txt6" style="display: none;">テキスト6テキスト6テキスト6テキスト6</div>
    <div class="js-change-txt7" style="display: none;">テキスト7テキスト7テキスト7テキスト7</div>
    <div class="js-change-txt8" style="display: none;">テキスト8テキスト8テキスト8テキスト8</div>
  </div>


  <!-- サムネイル -->
  <div class="c-gallery__thumbs">
    <div class="js-change-img1"><img src="images/sample01.jpg" alt=""></div>
    <div class="js-change-img2"><img src="images/sample02.jpg" alt=""></div>
    <div class="js-change-img3"><img src="images/sample03.jpg" alt=""></div>
    <div class="js-change-img4"><img src="images/sample04.jpg" alt=""></div>
    <div class="js-change-img5"><img src="images/sample05.jpg" alt=""></div>
    <div class="js-change-img6"><img src="images/sample06.jpg" alt=""></div>
    <div class="js-change-img7"><img src="images/sample07.jpg" alt=""></div>
    <div class="js-change-img8"><img src="images/sample08.jpg" alt=""></div>
  </div>

</div>

低レベルな質問ですみません。
よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Kosuke_Shibuya

    2018/07/20 02:03

    HTML部分を提示してもらうと、多分3行くらいになると思います。

    キャンセル

  • takopo

    2018/07/20 02:10

    ご返信ありがとうございます。html部分を追加してみました。クラス名の連番はどうしても必要そうです。

    キャンセル

  • Kosuke_Shibuya

    2018/07/20 02:11

    シンプルに記述するのはいいけど、「画像が切り替わるプログラム」を作っていることが読み取れるだけの分量は書いてください。

    キャンセル

  • takopo

    2018/07/20 02:28

    確かに説明不足でした…申し訳ございません。実際のソースを追加しましたので、見ていただけると助かります。

    キャンセル

回答 4

checkベストアンサー

+3

こんにちは。

HTMLを修正して、以下のように data属性を追加するのはいかがでしょうか?

修正前:

<button class="btn1">ボタン1</button>
<button class="btn2">ボタン2</button>
<button class="btn3">ボタン3</button>
<button class="btn4">ボタン4</button>
<button class="btn5">ボタン5</button>

修正後:

<button class="btn" data-value="1">ボタン1</button>
<button class="btn" data-value="2">ボタン2</button>
<button class="btn" data-value="3">ボタン3</button>
<button class="btn" data-value="4">ボタン4</button>
<button class="btn" data-value="5">ボタン5</button>

上記の修正後のHTMLに対して、JSは以下のように、5つのボタンで
1個のクリックハンドラを共有させることができます。

修正後:

$(function() {
  $('.btn').on('click', function() {
    test($(this).data("value"));
  });

以下は上記の修正を示すデモです。

以上参考になれば幸いです。


補足1

ご質問に詳細なコードを追記される前に回答を書いてしまったので、ちょっと状況を誤読していたかもしれません。
その場合は、申し訳ありませんが、私の回答は無視してください。
  
補足2

どのボタンがクリックされたのかを示す、1から5の数字を、クリックされたボタンの位置を示すインデクスに 1を加えて得ることにすれば data-属性も不要で、以下のようにも出来るかと思います。

  $('.btn').each(function(i) { 
    $(this).on('click',  function() { test(i+1); } );
  });

例: https://jsfiddle.net/jun68ykt/f7k6t9wz/18/

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/20 03:32

    ご返信遅くなってすみません。今回data属性というものを初めて知ったのですが、クラスに連番を書くよりも分かりやすく、cssとの衝突の心配もなく良さそうですね。ご回答いただいたやり方で今プログラムを修正してみました所、無事に動作しました!
    今回はイベント部分をシンプルにするのが目的だったのですが、ご回答いただいたすべてのご意見は大変参考になるものばかりでした。
    今回はdata属性を使用するのが良さそうかなと思いましたので、上の方にもお教えいただいたのですが、先にご回答いただいたjun68ykt様をベストアンサーとさせていただきたいと思います。
    他の方も本当にありがとうございました。

    キャンセル

  • 2018/07/20 03:38

    > 無事に動作しました!

    とのことでよかったです!

    キャンセル

+3

クラスやIDに連番をつけるのは、保守性などの面でオススメしない。
jQuery を利用しているのなら、$(this)の出番です。

<!DOCTYPE HTML>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .btn {
                border: 1px solid #333;
            }
        </style>
    </head>
    <body>
        <div>
            <img class="btn btn-hover" src="https://dummyimage.com/200x60/000/fff&text=Black" data-altimage="https://dummyimage.com/200x60/000/fff&text=White" />
            <img class="btn btn-hover" src="https://dummyimage.com/200x60/000/fff&text=Black" data-altimage="https://dummyimage.com/200x60/000/fff&text=White" />
            <img class="btn btn-hover" src="https://dummyimage.com/200x60/000/fff&text=Black" data-altimage="https://dummyimage.com/200x60/000/fff&text=White" />
            <img class="btn btn-hover" src="https://dummyimage.com/200x60/000/fff&text=Black" data-altimage="https://dummyimage.com/200x60/000/fff&text=White" />
            <img class="btn btn-hover" src="https://dummyimage.com/200x60/000/fff&text=Black" data-altimage="https://dummyimage.com/200x60/000/fff&text=White" />
        </div>
        <script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
        <script type="text/javascript">
            $(function () {
                $("img.btn-hover").on('click', function () {
                    $(this).prop('src', $(this).data('altimage'));
                });
            });
        </script>
    </body>
</html>

追記の前に回答書いたから、やりたいこととずれてるかも。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/20 02:44

    ご返信ありがとうございます。確かに連番をつけるのは項目が増えたときが大変なので良くなさそうですね。書いていただいた内容も自分にとっては勉強になりますので感謝しております。

    キャンセル

  • 2018/07/20 02:46

    それだけではなくて、項目数が増えたときに、JavaScript部分は変更がないですよね。

    キャンセル

  • 2018/07/20 03:08

    なるほど、そういう理由もあるのですね。スクリプトを変更しないようにするのが、保守性の面で重要だということが分かり大変参考になりました。ありがとうございます。

    キャンセル

+3

HTML5なら data-* 属性を使うのもありです。
https://codepen.io/anon/pen/XBNjLK

<img class="button" data-num="1" src="http://via.placeholder.com/150x50">
<img class="button" data-num="2" src="http://via.placeholder.com/150x50">
<img class="button" data-num="3" src="http://via.placeholder.com/150x50">
<img class="button" data-num="4" src="http://via.placeholder.com/150x50">
<img class="button" data-num="5" src="http://via.placeholder.com/150x50">

HTMLではクラスを同じものにしておいて、JS上で使いたい値を data-num などの値で指定しておきます。
これを dataset から受け取って処理することができます。

$("img.button").on("click", function () {
  console.log(this.dataset.num);
})

ただし、実行してみるとわかりますが、この時点では num の値は文字列ですので、数値として扱いたい場合は変換する必要があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/20 03:41

    data-属性についてためになる方法をお教えいただきありがとうございます。こちらを使ってソースをシンプルにすることができました。今回は先にご回答いただいたこともあり、jun68ykt様をベストアンサーとさせていただきました。申し訳ございません…ご教授いただきましたこと大変感謝しております。

    キャンセル

+1

こういうときの為のfor文です。
アイデア次第で色々と出来るので使い方はおさえておきましょ。

まずは基本形

$(function() {
  for (var i = 0; i < 5; i++) {
    $('.btn' + i).on('click', function() {
      test(i);
    });
  }
});

配列を用意してからfor...ofを利用する

$(function() {
  var targets = [
    {class: 'btn1', num: 1},
    {class: 'btn2', num: 2},
    {class: 'btn3', num: 3},
    {class: 'btn4', num: 4},
    {class: 'btn5', num: 5}
  ];
  for (var it of targets) {
    $(it.class).on('click', function() {
      test(it.num);
    });
  }
});

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/20 02:42

    ご回答ありがとうございます。
    for文を使うことは気付きませんでした。こういった方法もあるのですね、大変参考になりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • JavaScript

    17514questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    7106questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。