みなさん、お疲れ様です。
今回の制作物は、カルーセルです。
早速デモをご覧ください。フリックでも画像切り替えできるので、スマホでも見てみてください。
コードです。HTMLで画像の数を変更したら、他は自動的に対応してくれるようになっています。
HTML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<section> | |
<div class="list-wrapper"> | |
<div class="list01"> | |
<div><img src="images/ichigo.gif" alt="いちご"></div> | |
<div><img src="images/kiwi.gif" alt="キウイ"></div> | |
<div><img src="images/mikan.gif" alt="みかん"></div> | |
<div><img src="images/ringo.gif" alt="りんご"></div> | |
</div> | |
</div> | |
<ul class="btn"> | |
<li class="prev"><</li> | |
<li class="next">></li> | |
</ul> | |
<div class="list02"> | |
</div> | |
</section> |
CSS(抜粋)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.list-wrapper{ | |
position: relative; | |
height: 200px; | |
overflow: hidden; | |
} | |
.photo{ | |
position: absolute; | |
top: 0; | |
font-size: 0; | |
} | |
.photo div{ | |
display: inline-block;/*横並びにする*/ | |
width: 100%; | |
max-width: 300px; | |
height: 200px; | |
overflow: hidden; | |
} | |
.pager div{ | |
display: inline-block;/*横並びにする*/ | |
color: gray; | |
font-size: 2rem;/*●の大きさ*/ | |
text-align: center; | |
cursor: pointer; | |
} |
jQuery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var photoWidth = $('.photo div').width();//画像一つの幅を取得 | |
var photoLength = $('.photo div').length;//画像の数を取得 | |
$('.photo').css({'width':photoWidth * (photoLength)});//画像を入れている箱の大きさを決定 | |
$('.list-wrapper').css({//画像が一つだけ見えるように大きさを設定 | |
'width':photoWidth, | |
'height':($('.photo').height())//子要素がposition:absoluteなので高さを設定 | |
}); | |
for(i=0;i<photoLength;i++){//画像の数だけ●ボタンを作成 | |
$('.pager').prepend('<div>●</div>'); | |
} | |
$('.pager div:first-child').css({'color':'orange'});//初めの●をオレンジ色に | |
$('.btn,.pager').css({'width':photoWidth});//ボタンの入る箱の大きさを画像一つ分の大きさに設定 | |
$('.pager div').css({//●のdivの大きさを均等になるように設定 | |
'width':(photoWidth / photoLength), | |
'height':(photoWidth / photoLength) | |
}); | |
var j = 0;//画像位置の初期値 | |
$('.next').on('click',carouselRight);//右ボタンを押したとき | |
$('.prev').on('click',carouselLeft);//左ボタンを押したとき | |
function carouselRight(){//右方向にスライド | |
if(j == (photoLength - 1)){//最後の画像だったら | |
$('.photo').animate({'left':0});//一番左に移動 | |
j = 0;//画像位置を最初にする | |
pagerChange(); | |
}else{//最後じゃなかったら | |
j++;//画像位置を一つ進める | |
$('.photo').animate({'left':-photoWidth * j},1000);//画像を一つ右に進める | |
pagerChange(); | |
} | |
} | |
function carouselLeft(){//左方向にスライド | |
if(j == 0){//最初の画像だったら | |
$('.photo').animate({'left':-photoWidth * (photoLength - 1)});//一番右に移動 | |
j = (photoLength - 1);//画像位置を最後にする | |
pagerChange(); | |
}else{//最初じゃなかったら | |
j--;//画像位置を一つ戻す | |
$('.photo').animate({'left':-photoWidth * j},1000);//画像を一つ左に進める | |
pagerChange(); | |
} | |
} | |
for(k=0;k<photoLength;k++){//画像の数だけ繰り返し | |
changePhoto(k); | |
} | |
function changePhoto(num){//押したボタンに紐づいてスライド | |
$('.pager div:nth-child(' + (num+1) + ')').on('click',function(){//num+1番目の●をクリックしたとき | |
$('.photo').animate({'left':(-photoWidth * num) + 'px'},1000);//その順番の画像に移動 | |
j = num;//画像位置を合わせておく | |
pagerChange(); | |
}); | |
} | |
function pagerChange(){//●の色を変える | |
$('.pager div').css({'color':'gray'});//一度全部グレーにする | |
$('.pager div:nth-child(' + (j+1) + ')').css({'color':'orange'});//今クリックしたもののみオレンジにする | |
} | |
//タッチイベント | |
var touchS; | |
var touchM; | |
$('.photo').on('touchstart',function(){//タップしたとき | |
touchS = event.changedTouches[0].pageX;//タップの指の位置を取得 | |
}); | |
$('.photo').on('touchmove',function(){//指を動かしたとき | |
touchM = event.changedTouches[0].pageX//動かした指の位置を取得 | |
}); | |
$('.photo').on('touchend',function(){//指を離したとき | |
var direction = touchS - touchM;//最初と最後の指の位置の差を取得 | |
if(direction > 0){//上の値が正 = 左にフリック | |
carouselRight();//右に一つ画像を変更 | |
} else{//上の値が負 = 右にフリック | |
carouselLeft();//左に一つ画像を変更 | |
} | |
}); |
画像をdivの中で横並びにし、そのdivをposition:absoluteにしてleftの値を変えることでスライドさせています。
○今回使ったjQueryのいろいろ
・touchstart・・・タッチしたときのイベントを取得する。
・touchmove・・・タッチしてから数ミリ秒後のイベントを取得する。
・touchend・・・指を話した瞬間のイベントを取得する。
今回、初めてタッチイベントを実装したのですが、なかなかうまくいきませんでした。はじめは画像を切り替える関数をtouchmoveイベントに入れてたのですが、touchmoveイベントは押さえている間ずっと有効になってしまうので、画像の切り替えがうまくいきませんでした。touchendイベントに入れるとフリックで切り替えができるようになりました。
変数宣言もイベントの外でしてあげないと動きませんでした。
まだまだ不明点が多いので、勉強しつつ他の動きも実装したいと思います。
それでは。
参考にさせていただいたサイト
jQueryで作るフリックスライド – (1)無段階スライド
jQueryを使ったスライダーの作り方とその仕組み