どこよりも詳しい万能スライダーjQueryプラグインslick.jsの使い方
いろいろなスライダー・カルーセルjQueryプラグインを利用してみて、一番簡単でカスタマイズ性に富んだものがこのslickです。非常に便利な分、注意しなければならないこともあるので、その点も含めて紹介したいと思います。
導入
ダウンロード
http://kenwheeler.github.io/slick/
サイト上部のメニューのget it nowをクリックします。
Download Nowをクリックでダウンロードすることができます。
読み込み
<head>
...
<link href=".../path/to/slick.css" rel="stylesheet">
</head>
head 内で slick.css を読み込みます。
...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src=".../path/to/slick.min.js"></script>
</body>
</html>
</body> の直前で jquery と slick.min.js を読み込ませます。
slickの基本
$(function(){
$('.slider').slick();
});
これで、slickスライダーの準備はOKです。
カスタマイズ
オプション
slickには、たくさんのオプションが用意されています。これらをうまく組み合わせることで、複雑なスライダーを作成することもできます。
$('.slider').slick({
// 矢印キーでスライドを切り替えるか [初期値:true]
accessibility: true,
// スライドの高さが違うときに自動調整するか [初期値:false]
adaptiveHeight: false,
// 自動再生するか [初期値:false]
autoplay: true,
// 自動再生で切り替えする時間(ミリ秒) [初期値:3000]
autoplaySpeed: 3500,
// 前次ボタンを表示するか [初期値:true]
arrows: true,
// 別のスライドと連携したいときにクラス名を指定 [初期値:null]
asNavFor: null,
// 矢印ボタンの生成位置を変更 [初期値:$('.my-slide)]
appendArrows: $('.my-slide'),
// ドットナビゲーションの生成位置を変更 [初期値:$('.my-slide)]
appendDots: $('.my-slide'),
// 前ボタンの要素を変更 [初期値:'']
prevArrow: '前へ',
// 次ボタンの要素を変更 [初期値:'']
nextArrow: '次へ',
// slidesToShowが奇数のとき、現在のスライドを中央に表示するか [初期値:false]
centerMode: false,
// centerMode:trueのとき、左右のスライドをチラ見せさせる幅 [初期値:'50px']
centerPadding: '60px',
// ease-in,ease-in-outなどCSSのイージング [初期値:'ease']
cssEase: 'linear',
// dots:trueのとき、ドットをサムネイルなどにカスタマイズ [初期値:n/a]
customPaging: function(slick, index){
var num = slick.$slides.eq(index).html();
return '' + num + '';
},
// ドットナビゲーションを表示するか [初期値:false]
dots: false,
// ドットナビゲーションのクラス名を変更 [初期値:slick-dots]
dotsClass: 'my-dots',
// マウスドラッグでスライドの切り替えをするか [初期値:true]
draggable: true,
// スライド切り替えをフェードするか [初期値:false]
fade: false,
// クリックでメインのスライドを切り替えるか
focusOnSelect: true,
// jQueryのイージング [初期値:'linear']
easing: 'linear',
// スライドをループさせるか [初期値:true]
infinite: false,
// infinite:falseのとき、両端のスライドをドラッグしようとした際のバウンドスクロール値 [初期値:0.15]
edgeFriction: 0.2,
// 開始スライド(0から始まるので注意) [初期値:0]
initialSlide: 2,
// 画像の遅延表示タイプ(ondemand/progressive) [初期値:'ondemand']
lazyLoad: 'ondemand',
// モバイルファーストにするか [初期値:false]
mobileFirst: false,
// autoplay:trueのとき、マウスフォーカスしたら一時停止させるか [初期値:true]
pauseOnFocus: true,
// autoplay:trueのとき、マウスホバーしたら一時停止させるか [初期値:true]
pauseOnHover: true,
// autoplay:trueのとき、ドットナビゲーションをマウスホバーしたら一時停止させるか [初期値:false]
pauseOnDotsHover: false,
// レスポンシブ設定の基準(window/slider/min) [初期値:'window']
respondTo: 'window',
// レスポンシブ設定
responsive: [
{
breakpoint: 1024, // 600〜1023px
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: true
}
},
{
breakpoint: 600, // 480〜599px
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
},
{
breakpoint: 480, // 〜479px
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
],
// 行数 [初期値:1]
rows: 1,
// スライド部分の要素のタグ名 [初期値:'']
slide: 'div',
// rowsの値が2以上のとき、1行あたりに表示させるスライド数 [初期値:1]
slidesPerRow: 2,
// 表示させるスライド数 [初期値:1]
slidesToShow: 2,
// 一度に移動させるスライド数 [初期値:1]
slidesToScroll: 2,
// スライド/フェードさせるスピード(ミリ秒) [初期値:300]
speed: 400,
// スワイプを検知するか [初期値:true]
swipe: true,
// slidesToScrollの値に関係なく、マウスドラッグやスワイプでスライドさせる際は1スライドずつ動かす [初期値:false]
swipeToSlide: false,
// タッチでスライドさせるか [初期値:true]
touchMove: true,
// (1/touchThreshold)*スライダーの横幅 分マウスドラッグするとスライドされる [初期値:5]
touchThreshold: 5,
// CSSのtransitionを使用するか [初期値:true]
useCSS: true,
// CSSのtransformを使用するか [初期値:true]
useTransform: true,
// 横幅がバラバラなスライドにするか [初期値:false]
variableWidth: false,
// 縦方向にスライドさせるか [初期値:false]
vertical: true,
// 縦方向のスワイプを有効にするか [初期値:false]
verticalSwiping: false,
// スライドの順番を逆にするか [初期値:false]
rtl: false,
// スライドアニメーション中サムネイルをクリックしたとき反応させないか [初期値:true]
waitForAnimate: true,
// z-index値 [初期値:1000]
zIndex: 1000
});
イベント
var $slider = $('.slider');
$slider.slick();
$slider.on('afterChange', function(slick, currentSlide){
console.log('スライド切り替え後のイベント');
});
$slider.on('beforeChange', function(slick, currentSlide, nextSlide){
console.log('スライド切り替え前のイベント');
});
$slider.on('breakpoint', function(event, slick, breakpoint){
console.log('ブレイクポイント時のイベント');
});
$slider.on('destroy', function(event, slick){
console.log('スライダーを解除(unslick)した時のイベント');
});
$slider.on('edge', function(slick, direction){
console.log('infinite:falseのとき両端のスライドをドラッグした時のイベント');
});
$slider.on('init', function(slick){
console.log('スライダーが初期化された時のイベント');
});
$slider.on('reInit', function(slick){
console.log('スライダーが再初期化された時のイベント');
});
$slider.on('setPosition', function(slick){
console.log('スライダのポジションまたは横幅が設定された時のイベント');
});
$slider.on('swipe', function(slick, direction){
console.log('マウスドラッグまたはスワイプされた時のイベント');
});
$slider.on('lazyLoaded', function(event, slick, image, imageSource){
console.log('画像がlazyLoadされる度に呼ばれるイベント');
});
$slider.on('lazyLoadError', function(event, slick, image, imageSource){
console.log('画像がlazyLoadされなかったときに呼ばれるイベント');
});
メソッド
var $slider = $('.slider');
$slider.slick();
// スライド切り替えの度にスライド番号を取得
$slider.on('afterChange', function(slick, currentSlide){
var current_slide = $my_slide.slick('slickCurrentSlide');
console.log(current_slide);
});
// 指定のスライドへ移動
$slider.slick('slickGoTo', 3);
// 次のスライドへ移動
$slider.slick('slickNext');
// 前のスライドへ移動
$slider.slick('slickPrev');
// スライドの自動再生を停止
$slider.slick('slickPause');
// スライドの自動再生を開始
$slider.slick('slickPlay');
// 末尾にスライドを追加
$slider.slick('slickAdd', 'Add Slide');
// 2番目(0から数えて)の位置にスライドを追加
$slider.slick('slickAdd', 'Add Slide', 1);
// 1番目(0から数えて)の位置にスライドを追加
$slider.slick('slickAdd', 'Add Slide', 1, 'addBefore');
// 3番目(0から数えて)のスライドを削除
$slider.slick('slickRemove', 2);
// 1番目(0から数えて)のスライドを削除
$slider.slick('slickRemove', 2, true);
// 2番目(0から数えて)のスライドを削除
$slider.slick('slickRemove', 2, false);
// jQueryの.filterと同じ機能
$slider.slick('slickFilter', function(index){
if (index < 2){
return $(this).eq(index); // スライド番号が2より小さいものだけ表示
}
});
// フィルターを解除
$slider.slick('slickUnfilter');
// スライダーのオプションを取得
var get_slick_option = $slider.slick('slickGetOption', 'infinite');
console.log(get_slick_option);
// スライダーのオプションを変更(第4引数をtrueにするとリアルタイムに反映)
$slider.slick('slickSetOption', 'infinite', false, true);
// スライダーを解除
$slider.slick('unslick');
// スライダーオブジェクトを取得
var slick_obj = $slider.slick('getSlick');
console.log(slick_obj);
ロード中は非表示に
Webサイトが表示されてからslickスライダーが初期化までの間、少しだけラグがあります。この間、スライドが縦に並んだり、画像が元サイズで表示されたりしてしまいます。他サイトを見てみると、フェードインでごまかす、0.3秒後に表示させるなど、非常に適当な説明で済ましてしまっています。しかし、slickはちゃんとそのようなことも考えて設計されています。slickスライダーが初期化されると、.slick-initialized というクラスが付与されます。これを利用します。
.slider {
display:none;
}
.slider.slick-initialized {
display: block;
}
たったこれだけでロード後に表示させることができます。
コンテナで囲っているとき
$('.slider').slick();
この場合、ロード後には次のようになります。
ロードされるまで、.slider-container 全体を非表示にしておきたいのですが、.slick-initialized クラスが追加されるのは、その子要素の .slider です。
このようなときには、自分で .initialized クラスを追加する必要があります。
$('.slider').on('init', function(){
$('.slider-container').addClass('initialized');
});
$('.slider').slick();
.slider-container {
display: none;
}
.slider-container.initialized {
display: block;
}
CSSは先ほどと同じような感じです。
slidesToShowが2以上のとき
$('.slider').on('setPosition', function(){
var slider_width = $slider.width(),
slide_gutter = $slider.find('.slick-slide').eq(0).css('margin-right').split('px')[0],
slides_num = $slider.slick('slickGetOption', 'slidesToShow'),
slide_width = (slider_width - slide_gutter * (slides_num - 1)) / slides_num;
$slider.find('.slick-active').css('width', slide_width + 'px');
});
slickスライダーはスライドの横幅が必ず整数pxになるようにしてあります。しかし、これは小数点以下が表示されないため、微妙にスライド間に隙間が空いたりする原因になります。そこで、小数点以下まで表示させるように記述してやります。
矢印ボタンを設置
<head>
...
</head>
矢印ボタンにはFontAwesomeを使用します。CDNから読み込んでおきます。
.slider-container {
position: relative;
}
.slider {
display: none;
margin: 0 24px;
overflow: hidden;
}
.slider.slick-initialized {
display: block;
}
.slider-arrow {
position: absolute;
top: 50%;
height: 36px;
margin-top: -18px; /* 高さの半分だけネガティブマージン */
color: #bd77f2;
line-height: 36px;
font-size: 28px;
cursor: pointer;
z-index: 10; /* 重要 */
}
.slider-prev {
left: 0;
}
.slider-next {
right: 0;
}
.slick-slide {
padding: 1.5em 0;
color: #fff;
text-align: center;
font-size: 1.1em;
outline: 0;
background-color: #bd77f2;
}
var $slider_container = $('.slider-container'),
$slider = $('.slider');
$slider.slick({
appendArrows: $slider_container,
// FontAwesomeのクラスを追加
prevArrow: '',
nextArrow: '',
});
ガター
.slider-container {
display: none;
position: relative;
}
.slider-container.initialized {
display:block;
}
.slider {
margin: 0 24px;
overflow: hidden;
}
.slick-list {
margin-right: -12px; /* ガター分ネガティブマージン */
}
.slider-arrow {
position: absolute;
top: 50%;
height: 36px;
margin-top: -18px; /* 高さの半分だけネガティブマージン */
color: #bd77f2;
line-height: 36px;
font-size: 28px;
cursor: pointer;
z-index: 10; /* 重要 */
}
.slider-prev {
left: 0;
}
.slider-next {
right: 0;
}
.slick-slide {
margin-right: 12px; /* ガター */
}
.slick-slide {
padding: 1.5em 0;
color: #fff;
text-align: center;
font-size: 1.1em;
outline: 0;
background-color: #bd77f2;
}
var $slider_container = $('.slider-container'),
$slider = $('.slider');
// スライド初期化時にクラスを追加
// はじめはdisplay:noneしておき、.initializedが追加されたらdisplay:block
$slider.on('init', function(){
$slider_container.addClass('initialized');
});
$slider.slick({
appendArrows: $slider_container,
prevArrow: '',
nextArrow: '',
slidesToShow: 3
});
// スライドの横幅を小数点以下pxまで表示
$slider.on('setPosition', function(){
var slider_width = $slider.width(),
slide_gutter = $slider.find('.slick-slide').eq(0).css('margin-right').split('px')[0],
slides_num = $slider.slick('slickGetOption', 'slidesToShow'),
slide_width = (slider_width - slide_gutter * (slides_num - 1)) / slides_num;
$slider.find('.slick-active').css('width', slide_width + 'px');
});
ネガティブマージンを使って、スライドとスライドのガター(間隔)を設定します。
サムネイルナビゲーション
.slider-container, .slider-nav-container {
display: none;
position: relative;
}
.slider-container.initialized, .slider-nav-container.initialized {
display: block;
}
.slider-nav-container {
margin-top: 18px;
}
.slider {
overflow: hidden;
}
.slider-nav {
margin: 0 26px;
}
.slider-arrow {
position: absolute;
top: 50%;
height: 36px;
margin-top: -18px; /* 高さの半分だけネガティブマージン */
color: #aaa;
line-height: 36px;
font-size: 28px;
cursor: pointer;
z-index: 10; /* 重要 */
}
.slider-prev {
left: 0;
}
.slider-next {
right: 0;
}
.slick-slide {
outline: 0;
}
.slider .slick-slide > img, .slider-nav .slick-slide > img {
display: block;
width: 100%;
height: auto;
}
var $slider_container = $('.slider-container'),
$slider = $('.slider'),
$slider_nav_container = $('.slider-nav-container'),
$slider_nav = $('.slider-nav');
// ナビゲーション用に複製
$slider_nav.append($slider.contents().clone());
// スライド初期化時にクラスを追加
// はじめはdisplay:noneしておき、.initializedが追加されたらdisplay:block
$slider.on('init', function(){
$slider_container.addClass('initialized');
});
$slider_nav.on('init', function(){
$slider_nav_container.addClass('initialized');
});
$slider.slick({
arrows: false,
asNavFor: $slider_nav,
fade: true,
waitForAnimate: false
});
$slider_nav.slick({
appendArrows: $slider_nav_container,
prevArrow: '',
nextArrow: '',
slidesToShow: 3,
asNavFor: $slider,
focusOnSelect: true,
centerMode: true,
centerPadding: '40px'
});
// スライドの横幅を小数点以下pxまで表示
// 今回はcenterPaddingもあるのでその分も計算しています
$slider_nav.on('setPosition', function(){
var slider_width = $slider_nav.width(),
slide_gutter = $slider_nav.find('.slick-slide').eq(0).css('margin-right').split('px')[0],
slides_num = $slider_nav.slick('slickGetOption', 'slidesToShow'),
slides_center_padding = $slider_nav.slick('slickGetOption', 'centerPadding').split('px')[0],
slide_width = (slider_width - slide_gutter * (slides_num - 1) - (slides_center_padding * 2)) / slides_num;
$slider_nav.find('.slick-slide').css('width', slide_width + 'px');
});
こんな感じで簡単に複雑なスライダーを作成することができます。asNavFor で互いのスライダーを指定することで連携ができます。
複数のスライダー
var $slider_container = $('.slider-container'),
$slider = $('.slider');
$slider.each(function(index){
$slider.eq(index).slick({
appendArrows: $slider_container.eq(index),
prevArrow: '',
nextArrow: '',
});
});
複数のスライダーを使用するときは注意が必要です。スライダーごとにクラス名を変えればいいのですが、それだとJavaScriptの記述が増えてしまいます。そこで、スライダーを each で回し、eq() 関数を使って、何番目のスライダーを操作しているかを明確に指定します。これで、いくつスライダーが増えたとしても大丈夫です。