menu

はとむぎ

独学でプログラミングを勉強中、現在(2019年8月)はPHPを勉強しています。 WEBサイト制作(WordPress対応)をとりあえずの目標としております!! それとゲーム実況もやっております!見ていて楽しいと思ってもらえる放送をしたいと日々試行錯誤しております。

H&Rブログ > JavaScript > スライド > 画像をクリックしたらスライドする機能|解説付き

画像をクリックしたらスライドする機能|解説付き

JavaScript




どうもRyokutyaです。
今回はスライドの画像部分をクリックすると画像がスライドする機能を追加していきます。

今回やること

スライドの画像部分の右側をクリックすると画像が1つ進む、左側をクリックすると画像が一つ戻る機能を追加します。

コードの紹介

今回もまずはコードの紹介をします。
Javascript以外は前回と変更点がありませんが、コピペ用に全て記載しています。
よかったら使ってください。


html

<section class="carousel">
  <div class="carousel_h">
    <h1>Carousel 1</h1>
  </div>

<div class="slider_wrapper">
        <p class="slider_title">carousel  スライド移動</p>

          <div class="slides_container">
            <div class="slides_inner">
              <ul class="slides" id="slide_case">
                <li class="slide"><img src="./img/1.png" alt=""></li>
                <li class="slide"><img src="./img/2.png" alt=""></li>
                <li class="slide"><img src="./img/3.png" alt=""></li>
                <li class="slide"><img src="./img/4.png" alt=""></li>
                <li class="slide"><img src="./img/5.png" alt=""></li>
              </ul>
            </div>
          </div>

          <!-- prev,next_btn -->
            <div class="prev_btn"></div>
            <div class="next_btn"></div>
        <div class="index_btn_wrapper">
          <ul id="index_btn_cover" class="">
          </ul>
        </div>
      </div>
</section>


css

.carousel {
  padding-top: 20px;
  padding-bottom: 20px;
}

.slider_title {
  font-size: 32px;
  text-align: center;
}

.slides_container {
  padding: 0 50px;
  position: relative;
}

.slides_container .slides_inner {
  text-align: center;
  max-width: 800px;
  margin: 0 auto;
  white-space: nowrap;
  letter-spacing: -0.4em;
  overflow: hidden;
}

.slides_container .slides {
  list-style: none;
  transition: transform 2s ease 0s;
  padding-left: 0;
}

.slides_container .slides img {
  width: 100%;
  height: 500px;
}

.slide {
  display: inline-block;
}

.prev_btn {
  border-left: 3px solid #000;
  border-bottom: 3px solid #000;
  width: 30px;
  height: 30px;
  transform: rotate(45deg);
  position: absolute;
  top: 50%;
  left: 100px;
  cursor: pointer;
}

.next_btn {
  border-right: 3px solid #000;
  border-bottom: 3px solid #000;
  width: 30px;
  height: 30px;
  transform: rotate(-45deg);
  position: absolute;
  top: 50%;
  right: 100px;
  cursor: pointer;
}

.index_btn {
  background-color: red;
  color: white;
  text-align: center;
  width: 40px;
  height: 40px;
  line-height: 40px;
  display: inline-block;
  margin-right: 10px;
  font-size: 20px;
  cursor: pointer;
}

.index_btn_wrapper {
  padding-top: 40px;
  text-align: center;
}


JavaScript+jQuery

   let slideList=$('.slide');
    let slideLength=slideList.length;
    let index=0;

    //=================================================//
    //indx_btnの作成
    //=================================================//

    for(i=0; i<slideLength; i++){
        let indexBtn=document.createElement('li');
        indexBtn.id="index_btn"+i;
        indexBtn.className="index_btn";
        indexBtn.textContent=i+1;
        document.getElementById('index_btn_cover').insertBefore(indexBtn,null);
    }

    //=================================================//
    //index_btnの色変えの制御 (new)
    //=================================================//
    $('.index_btn').eq(0).addClass('active');//1つめのボタンにactive(クラス)を付与
    function activeMethod(){
        $('.index_btn').eq(index).addClass('active');
        $('.index_btn').not($('.index_btn').eq(index)).removeClass('active');
    }
    

  
    //=================================================//
    //inddex_btnを押した時の制御
    //=================================================//

    //スライドしながら移動
    $('.index_btn').click(function(){
        //index()は使用するときindex($())となることに注意
        index=$('.index_btn').index($(this));
        $('.slides').css('transform','translate('+(index*-100)+'%)');
    });

    
    //=================================================//
    //next_btnを押した時の制御(new)
    //=================================================//

    function nextSlide(){
        index+=1;
        if(index < slideLength){
            $('.slides').css('transform','translate('+(index*-100)+'%)');
        }else{
            index=0;
            $('.slides').css('transform','translate(0)');
        }
    }
    
    $('.next_btn').click(function(){
       nextSlide();
    });

    //=================================================//
    //prev_btnを押した時の制御 (new)
    //=================================================//

    function prevSlide(){
        index-=1;
        if(index === -1){
            index=slideLength-1;
            $('.slides').css('transform','translate('+(index*-100)+'%)');
        }else{
            $('.slides').css('transform','translate('+(index*-100)+'%)');
        }
    }

    $('.prev_btn').click(function(){
       prevSlide();
    });
    
    //=================================================//
    //画像をクリックした時の制御(new)
    //=================================================//

    $('.slide').click(function(e){
       let clickPoint=e.offsetX;
       let slideWidth=$('.slide').width();
       let clickWidth=1/6;//スライドのクリックできる幅

       if( clickPoint<slideWidth*clickWidth ){
           prevSlide();
       }

       if( slideWidth-(slideWidth*clickWidth)<clickPoint && clickPoint<slideWidth ){
           nextSlide();
        }
       
    });

コードの説明

今回の変更点はJavaScriptだけです。(html,cssに変更点はありません)
変更点があった部分には(new)を記載しています。

画像をクリックした時の制御

    
    //=================================================//
    //画像をクリックした時の制御 (new)
    //=================================================//

    $('.slide').click(function(e){
        let clickPoint=e.offsetX;
        let slideWidth=$('.slide').width();
        let clickWidth=1/6;//スライドのクリックできる幅
 
        if( clickPoint < slideWidth*clickWidth ){
            prevSlide();
        }
 
        if( slideWidth-(slideWidth*clickWidth) < clickPoint && clickPoint < slideWidth ){
            nextSlide();
         }
        
     });

まず、画像をクリックした時画像が移動する方法を以下のステップで説明します。
①画像がクリックされた時に作動する
②画像のどの部分がクリックされたか判別する
③クリックされた場所によって動作を条件分岐する
④スライドを変更する処理

画像がクリックされた時に作動する

画像をクリックしたときに作動して欲しいので対象要素を画像が入っている要素(.slide)にしてクリックイベントを記述しています。
クリックイベント内でクリックした時に処理したい内容を記載しています。

画像のどの部分がクリックされたか判別する

画像の右側をクリックした時と左側をクリックした時で異なる動作にしたいため、画像のどの部分がクリックされたか判別する必要があります。

let clickPoint=e.offsetX;

画像のどの部分がクリックされたかはこの一文だけで判別できます。
「画像がクリックされた時に作動」させるためにクリックイベントを使用していますが、クリックイベントを記述した際に引数にeを設定しています。
これはjQueryにもともと準備されているもので、「e.元々準備されているもの」とすることでいろいろな情報を取得することができます。
クリックイベントの引数は今回はeとしていますが、普通の引数と同じで名前は好きなものを指定できます。ですが、後々コードを見返したり他の人が見てもわかりやすいようにeeventとするのが普通です。
元々準備されているものの一つに、offsetXというものがあります。
これは、クリックされた要素の左上を原点として、クリックされた場所のX座標を取得でます。

offsetXをコンソールに表示

offsetXをコンソールに表示するとわかりやすいので、実際に使う時は確認しながら使ってみてください。
※画像はわかりやすいようにoffsetX:445と表示されるようにしていますが、実際は445の様に数字だけが取得されます。
Y座標が取得したい場合はoffsetYで取得することができます。
他にもいろいろな情報を習得することができますが、ここでは説明しきれないので、function(e)などで検索してみてください。
また、console.log(e)としてみるとクリックした場所の取得したデータをみることができるので1つ1つ調べてみるのもいいかもしれません。

コンソールにeを表示したもの

クリックされた場所によって動作を条件分岐する

let slideWidth=$('.slide').width();
        let clickWidth=1/6;//スライドのクリックできる幅
 
        if( clickPoint < slideWidth*clickWidth ){
            prevSlide();
        }
 
        if( slideWidth-(slideWidth*clickWidth) < clickPoint && clickPoint < slideWidth ){
            nextSlide();
         }

まず分岐の条件を設定します。
今回は画像の両端(画像の1/6の幅)をクリックした時に、画像が動くようにし、それ以外をクリックしても何も起こらに様にしています。

この条件にするためには画像の横幅を取得する必要があります。
対象要素.width()で対象要素の幅を取得できます。
対象要素.width()で取得できる幅はpadding,margin,borderの太さを含まない幅となることに注意してください。
paddingやmarginを含んだ幅を取得したい場合は、innerwidth,outerwidth,outerwidth(true)を検索して調べてみてください。

これで必要な情報が揃ったので条件分岐について考えていきます。
条件分岐は右側がクリックされた時と左側がクリックされた時の2つを考えます。
①左側の条件

 if( clickPoint < slideWidth*clickWidth ){
  prevSlide();
}

左側は画像の1/6の幅までをクリックされた時としたいので、clickPontが画像幅の1/6(clickWidth)より小さければ画像が「1つ戻る」ようにします。※clickPoint(変数)はクリックされた場所のX座標(e.offsetX)です。

②右側の条件

if( slideWidth-(slideWidth*clickWidth) < clickPoint && clickPoint < slideWidth ){
  nextSlide();
}

クリックされた場所のX座標が(clickPoint)がslideWidth-(slideWidth*clickWidth)より大きくかつ画像サイズより小さいときに画像が「1つ進む」ようにします。
これで「右側をクリックした時」、「左側をクリックした時」両方の条件分岐を設定することができました。
どちらの条件もfalseの時はなにも起こらなくていいので、記述はしていません。
クリックできる幅を変更したいときはclickWidth(変数)の値を変更することで変更できます。

スライドを変更する処理

//=================================================//
    //next_btnを押した時の制御 (new)
    //=================================================//

    function nextSlide(){
        index+=1;
        if(index < slideLength){
            $('.slides').css('transform','translate('+(index*-100)+'%)');
        }else{
            index=0;
            $('.slides').css('transform','translate(0)');
        }
    }
    
    $('.next_btn').click(function(){
       nextSlide();
    });

    //=================================================//
    //prev_btnを押した時の制御 (new)
    //=================================================//

    function prevSlide(){
        index-=1;
        if(index === -1){
            index=slideLength-1;
            $('.slides').css('transform','translate('+(index*-100)+'%)');
        }else{
            $('.slides').css('transform','translate('+(index*-100)+'%)');
        }
    }

    $('.prev_btn').click(function(){
       prevSlide();
    });
    
    //=================================================//
    //画像をクリックした時の制御 (new)
    //=================================================//

    $('.slide').click(function(e){
        let clickPoint=e.offsetX;
        let slideWidth=$('.slide').width();
        let clickWidth=1/6;//スライドのクリックできる幅
 
        if( clickPoint < slideWidth*clickWidth ){
            prevSlide();
        }
 
        if( slideWidth-(slideWidth*clickWidth) < clickPoint && clickPoint < slideWidth ){
            nextSlide();
         }
        
     });

スライドが「1つ進む」、「1つ戻る」処理については前回の記事で作った処理をそのまま使うことができますので、そのまま使っています。
コピペして使うのでもいいのですが、そうした場合変更が生じた場合「1つ進むボタン」と「画像の右側をクリックした時の処理」の2ヶ所を変更しなければいけないので、変更忘れの原因になります。
そのため、「1つ進む処理」と「1つ戻る処理」をそれぞれ関数に格納し、必要な場所で呼び出すように変更しています。
「1つ進む処理」をnextSlide(関数)、「1つ戻る処理」をprevSlide(関数)としています。

おわりに

今回は画像の両端をクリックしたときスライドが動くようにしました。
スライドの両端幅を変えることも簡単にできるので是非使っていただければと思います。
次回はスライドが移動した時連動してインデックスボタンの色が変わる方法について説明していきます。
それでは今回はこのあたりで(^^)/




コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

緑茶

2019年からフリーランスを目指して独学でwebデザインの勉強をしてきました。 相方のはとむぎと一緒にゲーム実況やブログの運営などをしています。 今後も相方と一緒に色々なことに挑戦していきたいです。

緑茶のカテゴリー

はとむぎ

独学でプログラミングを勉強中、現在(2019年8月)はPHPを勉強しています。 WEBサイト制作(WordPress対応)をとりあえずの目標としております!! それとゲーム実況もやっております!見ていて楽しいと思ってもらえる放送をしたいと日々試行錯誤しております。

緑茶

2019年からフリーランスを目指して独学でwebデザインの勉強をしてきました。 相方のはとむぎと一緒にゲーム実況やブログの運営などをしています。 今後も相方と一緒に色々なことに挑戦していきたいです。

緑茶のカテゴリー

アーカイブ

はとむぎ

独学でプログラミングを勉強中、現在(2019年8月)はPHPを勉強しています。 WEBサイト制作(WordPress対応)をとりあえずの目標としております!! それとゲーム実況もやっております!見ていて楽しいと思ってもらえる放送をしたいと日々試行錯誤しております。

緑茶

2019年からフリーランスを目指して独学でwebデザインの勉強をしてきました。 相方のはとむぎと一緒にゲーム実況やブログの運営などをしています。 今後も相方と一緒に色々なことに挑戦していきたいです。

緑茶のカテゴリー

アーカイブ