jQuery でレスポンシブ対応のコンテンツ スライダーを作ってみました。名前は『Liteslider』としました。
スライダー スクリプトはたくさん存在しますが、いろいろと応用したかったので自作することにしました。また、jQuery の animation を使用すれば簡単にできると思っていたことも要因の一つですが、意外と手こずってしまった(汗
Liteslider の特徴は下記のとおりです。
- 画面表示時(スクリプト実行時)にチラつかない
- レスポンシブ対応
- コンテンツ対応
- スライドショー
- アニメーションはスライドとフェードの2種類
使い方
スクリプトと CSS を読み込む
jQuery と liteslider.js、liteslider.css を読み込むように HTML に記述します。
<link rel="stylesheet" href="liteslider.css" type="text/css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="liteslider.js"></script>
スライドする画像(コンテンツ)を配置する
配置する場所に下記のように記述します。
liteslider、slides-container および slides クラスは必須です。slide-content クラスはコンテンツを表示する場合のみ記述します。
<div id="liteslider-1" class="liteslider">
<div class="slides-container">
<ul class="slides">
<li><img src="01.jpg" /></li>
<li><img src="02.jpg" /><div class="slide-content">ここにコンテンツを記述する。</div></li>
<li><img src="03.jpg" /></li>
</ul>
</div>
</div>
スライドを実行するスクリプト
スライドを実行するスクリプトを下記のように記述します。
<script type="text/javascript">
jQuery(function($) {
$("#liteslider-1").liteslider({
effect: "slide",
navigation: true,
pagination: true,
slideshow: true,
slideshowSpeed: 5000,
animationSpeed: 1000
});
});
</script>
オプション
プロパティ | デフォルト | 説明 |
effect | “slide” | アニメーション効果。 “fade” または “slide” を指定します。 |
navigation | true | ナビゲーションを表示するかどうか。 |
pagination | true | ページネーションを表示するかどうか。 |
slideshow | true | 自動でスライドショーするかかどうか。 |
slideshowSpeed | 5000 | スライドショーでスライドする間隔。ミリ秒単位で指定します。 |
animationSpeed | 1000 | アニメーション効果のスピード。ミリ秒単位で指定します。 |
スライダー本体
liteslider.js
/**
* jQuery Liteslider v1.0.1
* Copyright 2015 ishitaka
*/
;
jQuery(function($) {
$.fn.liteslider = function(options) {
var defaultOptions = {
effect: 'slide',
navigation: true,
pagination: true,
slideshow: true,
slideshowSpeed: 5000,
animationSpeed: 1000
};
var target = $(this);
var options = $.extend({}, defaultOptions, options);
var container = target.find('.slides-container');
var slideCount = target.find('.slides > li').length;
var slides = target.find('.slides');
var pagination;
var slideNo = 1;
var slideWidth = 0;
var slidePos = 0;
var isSlideAction = false;
function init() {
if (options.effect === 'slide') {
/* 最後のスライドから最初のスライドへアニメーションさせるため、最後に最初のスライドを追加 */
slides.append(slides.find('> li:first-child').clone(true));
} else {
slides.find('> li:not(:first-child)').css({position:"absolute", left:"0", top:"0", opacity:"0"});
}
if (options.navigation) {
target.append('<div class="slide-nav-prev"><</div><div class="slide-nav-next">></div>');
$(".slide-nav-prev").click(function() {
isSlideAction = true;
if (options.effect === 'slide') {
slidePrev();
} else {
fade(slideNo === 1 ? slideCount : slideNo - 1);
}
});
$(".slide-nav-next").click(function() {
isSlideAction = true;
if (options.effect === 'slide') {
slideNext();
} else {
fade(slideNo >= slideCount ? 1 : slideNo + 1);
}
});
}
if (options.pagination) {
var paginationHtml = '<ol class="slide-pagination">';
for (var i = 0; i < slideCount; i++) {
paginationHtml += '<li></li>';
}
paginationHtml += '</ol>';
target.append(paginationHtml);
pagination = target.find('.slide-pagination li');
pagination.click(function() {
isSlideAction = true;
var index = pagination.index(this);
if (options.effect === 'slide') {
slide(index + 1);
} else {
fade(index + 1);
}
});
pagination.eq(slideNo - 1).addClass('slide-active');
}
resize();
slides.find('> li').show();
}
function resize() {
slideWidth = container.width();
slides.find('li').css({"width": slideWidth + "px"});
if (options.effect === 'slide') {
slides.width((slideCount + 1) * slideWidth);
slidePos = (slideNo - 1) * slideWidth;
container.animate({scrollLeft: slidePos}, 1, "swing");
} else {
slides.width(slideWidth);
}
}
function slideNext() {
slidePos = ((slideNo - 1) * slideWidth);
container.animate({scrollLeft: slidePos}, 1, "swing", function() {
slideNo++;
slidePos = ((slideNo - 1) * slideWidth);
container.animate({scrollLeft: slidePos}, options.animationSpeed, "swing");
if (slideNo > slideCount) {
slideNo = 1;
}
if (options.pagination) {
pagination.removeClass('slide-active');
pagination.eq(slideNo - 1).addClass('slide-active');
}
});
}
function slidePrev() {
if (slideNo === 1) {
slideNo = slideCount + 1;
}
slidePos = ((slideNo - 1) * slideWidth);
container.animate({scrollLeft: slidePos}, 1, "swing", function() {
slideNo--;
slidePos = ((slideNo - 1) * slideWidth);
container.animate({scrollLeft: slidePos}, options.animationSpeed, "swing");
if (options.pagination) {
pagination.removeClass('slide-active');
pagination.eq(slideNo - 1).addClass('slide-active');
}
});
}
function slide(no) {
if (slideNo === no)
return;
slidePos = ((slideNo - 1) * slideWidth);
container.animate({scrollLeft: slidePos}, 1, "swing", function() {
slideNo = no;
slidePos = ((slideNo - 1) * slideWidth);
container.animate({scrollLeft: slidePos}, options.animationSpeed, "swing");
if (options.pagination) {
pagination.removeClass('slide-active');
pagination.eq(slideNo - 1).addClass('slide-active');
}
});
}
function fade(no) {
var slide = slides.find('> li');
$(slide[slideNo - 1]).animate({opacity: '0'}, options.animationSpeed);
$(slide[no - 1]).animate({opacity: '1'}, options.animationSpeed);
slideNo = no;
if (options.pagination) {
pagination.removeClass('slide-active');
pagination.eq(slideNo - 1).addClass('slide-active');
}
}
if (options.slideshow) {
setInterval(function() {
if (!isSlideAction) {
if (options.effect === 'slide') {
slideNext();
} else {
fade(slideNo >= slideCount ? 1 : slideNo + 1);
}
} else {
isSlideAction = false;
}
}, options.animationSpeed + options.slideshowSpeed);
}
$(window).resize(function() { resize(); });
init();
};
});
liteslider.css
.liteslider {
width: 100%;
height: auto;
position: relative;
}
.liteslider img {
max-width: 100%;
height: auto;
}
.liteslider .slides-container {
overflow: hidden;
}
.liteslider ul.slides {
margin: 0;
padding: 0;
list-style: none;
width: 100%;
max-width: none;
}
.liteslider ul.slides > li {
float: left;
text-align: center;
position: relative;
}
.liteslider ul.slides > li:not(:first-child) {
display: none;
}
.liteslider ul.slides:after {
content: "";
display: block;
clear: both;
}
.liteslider .slide-content {
position: absolute;
margin: 0;
padding: 10px;
top: 0;
left: 0;
width: 100%;
text-align: left;
}
/*
Navigation
*/
.liteslider .slide-nav-prev,
.liteslider .slide-nav-next {
position: absolute;
color: #333333;
font-size: 30px;
font-weight: bold;
text-align: center;
width: 40px;
height: 40px;
line-height: 40px;
cursor: pointer;
opacity: 0;
margin-top: -20px;
top: 50%;
z-index: 11;
}
.liteslider .slide-nav-prev {
left: 0;
}
.liteslider .slide-nav-next {
right: 0;
}
.liteslider:hover .slide-nav-prev,
.liteslider:hover .slide-nav-next {
opacity: 0.8;
}
.liteslider:hover .slide-nav-prev:hover,
.liteslider:hover .slide-nav-next:hover {
opacity: 0.5;
}
/*
Pagination
*/
.liteslider ol.slide-pagination {
position: absolute;
margin: 0;
padding: 0;
list-style-type: none;
bottom: 16px;
width: 100%;
height: 16px;
text-align: center;
z-index: 10;
}
.liteslider ol.slide-pagination li {
margin: 0 5px;
width: 14px;
height: 14px;
display: inline-block;
cursor: pointer;
background-color: #333333;
border-radius: 10px;
border: 2px solid rgba(255,255,255,0.3);
opacity: 0.5;
}
.liteslider ol.slide-pagination li:hover,
.liteslider ol.slide-pagination li.slide-active {
border: 2px solid rgba(255,255,255,0.4);
opacity: 1.0;
}
最後に
今後のバージョンアップとしては、サムネイル表示とタッチ スワイプに対応させる予定(?)です。
このスクリプトを組み込んだ WordPress プラグインを近いうちに公開する予定です。日本語版は既に完成しているのですが、英語が・・・。
追記: 最新の jQuery Liteslider はこちら。