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

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

ただいまの
回答率

87.59%

スライダーが勝手に連動?

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,268
退会済みユーザー

退会済みユーザー

下記のような画像スライダーがあるのですが、ご覧のように、スライダーABが勝手に連動してしまいます。

■実際の動作
https://jsfiddle.net/0q0wy0zk/

■そのコード

スライダーA
<section class="a">
    <div class="slider">
        <div class="slideSet">
            <div class="slide1 slide-a1 slide">画像a1</div>
            <div class="slide2 slide-a2 slide">画像a2</div>
        </div>
    </div>
</section>

スライダーB
<section class="b">
    <div class="slider">
        <div class="slideSet">
            <div class="slide1 slide-b1 slide">画像b1</div>
            <div class="slide2 slide-b2 slide">画像b2</div>
            <div class="slide3 slide-b3 slide">画像b3</div>
        </div>
    </div>
</section>
(function(){
    var slideWidth = $('.slide').outerWidth();    // .slideの幅を取得して代入
    var slideNum = $('.slide').length;    // .slideの数を取得して代入
    var slideSetWidth = slideWidth * slideNum;    // .slideの幅×数で求めた値を代入
    $('.slideSet').css('width', slideSetWidth);    // .slideSetのスタイルシートにwidth: slideSetWidthを指定

    var slideCurrent = 0;    // 現在地を示す変数

    // アニメーションを実行する独自関数
    var sliding = function(){
        // slideCurrentが0以下だったら
        if( slideCurrent < 0 ){
            slideCurrent = slideNum - 1;

        // slideCurrentがslideNumを超えたら
        }else if( slideCurrent > slideNum - 1 ){    // slideCUrrent >= slideNumでも可
            slideCurrent = 0;

        }

        $('.slideSet').stop().animate({
            left: slideCurrent * -slideWidth
        });
    }


    // 画像が押されたとき
    $('.slideSet').click(function(){
        slideCurrent++;
        sliding();
    });
}());
 .slideSet > div {
            width: 100px;
            height: 50px;
            border: 1px solid #f00;
            box-sizing: border-box;
        }

        .slide {
            float: left;
        }

        .slideSet {
            position: absolute;
        }

        .slider {
            width: 100px;
            height: 50px;
            overflow: hidden;
            position: relative;
        }

        .slide1 {
            background: red;
        }

        .slide2 {
            background: yellow;
        }

        .slide3 {
            background: aqua;
        }

        .slide4 {
            background: purple;
        }

        .slide5 {
            background: green;
        }


どなたか、それぞれのスライダーを独立させるような方法をご教示いただけませんでしょうか?

尚、スライダーの数はABCだったりABCDEFだったりと変化するので、AにはAのjavascriptを書いて、BにはBのjavascriptを書いて、、というのは避けたいです。

よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+2

.each()メソッドなどで.slideごとに処理すればいいかと思います。slideCurrentなどの変数はクロージャが作られるので問題ないかと。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/02/28 10:10

    難しそうですね。ご回答ありがとうございます。

    キャンセル

+1

スライダーが複数あるなら、共通部分をclassにまとめてしまうのが無難な気がします。
JavaScriptのclassは他の言語(C++, Java, PHP, ...)のclassと同じようなものです。他の言語の経験があれば、理解ができるかなと思います。

もし、今までclassに触れたことがないという場合は、学習をオススメします。

classを定義した後に、スライダー毎にnewを実行すれば、スライダー毎のインスタンスが生成できます。
スライダー毎に異なるもの(IDとかDOMとか)をコンストラクタの引数に設定すればよいと思います。
click処理やanimate処理は、classのメソッド(関数)として定義します。

ただ、JavaScriptのバージョンが古い場合、classが使えないこともあります。その場合は、代わりにprototypeというものを使えば、コード量が増えますが、同じようなことはできます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/02/28 17:00

    ありがとうございます。

    実はスライダーの画像はwordpressの記事ごとに大量に存在するので、

    >スライダー毎にnewを実行

    というのが億劫なのです。

    スライダー毎の設定をせず、一つのコードですべてのスライダーを一括で機能させることができればいいなと思っているのですが。。

    キャンセル

  • 2018/02/28 17:19

    ページ内のすべてのスライダーに対して、一括して設定をしたいなら、他の回答者様もおっしゃっているeachを使うことになると思います。

    Sliderというclassが存在している前提になってしまいますが、以下のように書けば、全てのスライダーのインスタンスを一気に生成できると思います。(動作確認はしていません。申し訳ありません)

    $('.slideSet').each(function(){
    new Slider($(this));
    });

    今回の場合、$('.slideSet')に該当する要素<div class="slideSet">は、2か所あります。
    $('.slideSet').each()は、for文みたいに、複数の要素を1つずつアクセスできるものと思ってください。$(this)でその要素にアクセスできます。
    これで、要素が何個あろうと、すべての要素に一気に設定ができます。

    この仕組みを使えば、何とかなるのではないでしょうか?

    キャンセル

  • 2018/03/01 05:55

    ありがとうございます。頭がパンクしてしまいましたが、幸運なことに別の方のご回答を戴きました。(^◇^)
    今回ベストアンサーは譲ってあげてください。

    キャンセル

  • 2018/03/01 08:37

    解決してよかったです

    キャンセル

checkベストアンサー

0

jsfiddleのJSを改修。
slideSet要素自体に定義していたデータを持たせています。
sliding関数にクリックした要素を渡し、実行しています。
他の回答者がおっしゃるように、最初のデータをセットするのにeachを使っています。
良ければお試しください。

(function(){

// 初期設定
$('.slideSet').each(function(index,element){
    var $this = $(element);
  var $slides = $this.find('.slide');
  $this.data('slideWidth' , $slides.eq(0).outerWidth());
  $this.data('slideNum' , $slides.length);
  $this.data('slideSetWidth' , 
                          $slides.eq(0).outerWidth() * $this.data('slideNum') );
  $this.css('width', $this.data('slideSetWidth'));


  $this.data('slideCurrent', 0);

});
    /* var slideWidth = $('.slide').outerWidth();    // .slideの幅を取得して代入
    var slideNum = $('.slide').length;    // .slideの数を取得して代入
    var slideSetWidth = slideWidth * slideNum;    // .slideの幅×数で求めた値を代入
    $('.slideSet').css('width', slideSetWidth);    // .slideSetのスタイルシートにwidth: slideSetWidthを指定

      var slideCurrent = 0; */


    // アニメーションを実行する独自関数
    var sliding = function($this){

        var slideCurrent = $this.data('slideCurrent');    // クリックした要素の現在地
        var slideNum = $this.data('slideNum');
        var slideWidth = $this.data('slideWidth');

        // slideCurrentが0以下だったら
        if( slideCurrent < 0 ){
            slideCurrent = slideNum - 1;

        // slideCurrentがslideNumを超えたら
        }else if( slideCurrent > slideNum - 1 ){    // slideCUrrent >= slideNumでも可
            slideCurrent = 0;

        }

        $this.stop().animate({
            left: slideCurrent * -slideWidth
        });

          $this.data('slideCurrent' , slideCurrent); // 移動したので再代入
    }


    // 画像が押されたとき
    $('.slideSet').click(function(){
        var $this = $(this);

          var num = $this.data('slideCurrent') + 1;
          $('body').append('<p>'+num+'</p>');
        $this.data('slideCurrent',num);
        sliding($this);
    });

}());

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/03/01 04:39

    わぁ、ありがとうございます。助かりました!大感謝です。
    ところで、<p>タグで数字を出しているのは、どうしてでしょうか?

    $('body').append('<p>'+num+'</p>');

    これがなくても動くので、これは何のためかなぁと思いまして。
    よろしければ教えてくださいませ。

    キャンセル

  • 2018/03/01 09:23

    あ、すいません。デバッグで適当に出力させてただけでした。消して問題ないです。

    キャンセル

  • 2018/03/01 10:10

    あ、なるほど。ありがとうございます。不安だったのでご回答いただけて良かったです。

    キャンセル

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

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

関連した質問

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