jQueryでシンプルなカルーセルを作る

タイトルの通り、jQueryでシンプルなカルーセルを作成します。
完成品はこちらです。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="rNZYeJL" data-user="910qdo" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/910qdo/pen/rNZYeJL">
  Untitled</a> by 910qdo (<a href="https://codepen.io/910qdo">@910qdo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
上から順を追って説明していきます。

カルーセルの中身を複製し、ループに備えます。
同時にドットも中身の数だけ生やして、先頭にviewクラスを付与します。

```diff_javascript
var carouselLength = $('.carousel li').length;
for(var i=1;i<=carouselLength;i++){
  $('.carousel_list').append($('.carousel_list li:nth-of-type(' + i + ')').clone());
  $('.carousel_dot').append('<li></li>');
}
$('.carousel_dot li:first-of-type').addClass('view');
```

表示内容の高さと幅を取得します。
今回は全て同じサイズという前提で作成しています。
自動で取得するのでCSS側での設定は不要です。

```diff_javascript
var carouselWidth = $('.carousel li').outerWidth();
var carouselHeight = $('.carousel li').outerHeight();
```

取得した高さと幅をセットしていきます。
```diff_javascript
$('.carousel_box, .carousel, .carousel li').css({
  'width': carouselWidth+ 'px',
  'height': carouselHeight + 'px'
});
```

.carousel_listには、先程複製したもの含め、中身をすべて横並びにした幅を追加します。
また、初期表示位置を先頭ではなく、二回目に一番目の要素が登場する位置に設定します。
こうすることで、左右どちらにも要素がある状態を作ります。
```diff_javascript
$('.carousel_list').css({
  'left': (carouselWidth * carouselLength * (-1)) + 'px',
  'width': (carouselWidth * carouselLength * 2) + 'px',
  'height': carouselHeight + 'px'
});
```

ひとつ前の要素に戻る動作です。
ボタンを押すと「最後の要素をクローンして先頭に挿入」「最後の要素を削除」「カルーセル全体を要素一つ分左にずらす」「カルーセル全体を右に移動（アニメーション）」の順に実行されます。
※carousel_riset関数とcarousel_dot関数については後程説明します。
```diff_javascript
$('.js__carousel_prev').click(function(){
  carousel_riset();
  $('.carousel_list').prepend($('.carousel_list li:last').clone());
  $('.carousel_list li:last').remove();
  $('.carousel_list').css({
    'margin-left': '-=' + carouselWidth
  });
  $('.carousel_list').animate({
    'left': '+=' + carouselWidth
  }, 700);
  carousel_dot();
});
```

ひとつ次の要素に進む動作です。
こちらは自動スクロールさせるため関数として呼び出します。
```diff_javascript
$('.js__carousel_next').click(function(){ carousel_next(); });
window.setInterval(carousel_next, 3500);
```
ボタンを押すと「先頭の要素をクローンして最後に挿入」「先頭の要素を削除」「カルーセル全体を要素一つ分右にずらす」「カルーセル全体を左に移動（アニメーション）」の順に実行されます。
```diff_javascript
function carousel_next(){
  carousel_riset();
  $('.carousel_list').append($('.carousel_list li:first').clone());
  $('.carousel_list li:first').remove();
  $('.carousel_list').css({
    'margin-left': '+=' + carouselWidth
  });
  $('.carousel_list').animate({
    'left': '-=' + carouselWidth
  }, 700);
  carousel_dot();
}
```

左右どちらかに要素幅*個数分動かしたら、カルーセルの位置をリセットする関数です。
これで数値が伸び続けることが無くなります。
先頭の「$('.carousel_list').stop(true, true);」はアニメーションを終了位置で停止させる関数です。
これで連打したら連打しただけカルーセルが動くようになります。
```diff_javascript
function carousel_riset(){
  $('.carousel_list').stop(true, true);
  if($('.carousel_list').css('margin-left') == (carouselWidth * carouselLength * (-1)) + 'px' || $('.carousel_list').css('margin-left') == (carouselWidth * carouselLength) + 'px' ){
    $('.carousel_list').css({
      'margin-left': 0,
      'left': (carouselWidth * carouselLength * (-1)) + 'px'
    });
  }
}
```

カルーセルと一緒にドットを操作します。
表示内容に合わせてviewクラスを付与する要素を変更しています。

```diff_javascript
function carousel_dot(){
  var mLeft = $('.carousel_list').css('margin-left');
  var dotPos = mLeft.replace('px', '') / carouselWidth + 1;
  if(dotPos == carouselLength + 1){
    dotPos = 1;
  }
  $('.carousel_dot li').removeClass('view');
  $('.carousel_dot li:nth-of-type(' + dotPos + ')').addClass('view');
}
```
以上で完成です。