カルーセルパネル(パネルをスライドして1周すると元のパネルに戻る)やスライドパネルを使う際のメモと練習(実用的でないものがほとんど)。
シンプルなカルーセルパネルを表示する。
HTML
<div id="slider_wrap"> <p id="slider_prev"><img src="images/slider-prev.png" alt="prev"></p> <p id="slider_next"><img src="images/slider-next.png" alt="next"></p> <div id="slider"> <div id="slider_inner"> <ul class="panel"> <li><a href="#"><img src="images/1.jpg" alt=""></a></li> <li><a href="#"><img src="images/2.jpg" alt=""></a></li> <li><a href="#"><img src="images/3.jpg" alt=""></a></li> <li><a href="#"><img src="images/4.jpg" alt=""></a></li> </ul> ・・・省略・・・ <ul class="panel"> <li><a href="#"><img src="images/13.jpg" alt=""></a></li> <li><a href="#"><img src="images/14.jpg" alt=""></a></li> <li><a href="#"><img src="images/15.jpg" alt=""></a></li> <li><a href="#"><img src="images/16.jpg" alt=""></a></li> </ul> </div><!-- end of #slider_inner --> </div><!-- end of #slider --> </div><!-- end of #slider_wrap -->
パネル全体を格納する div 要素(id=”slider_inner”)の幅を指定する必要があるが、パネルの数を変更できるように、jQuery で計算して指定する。
CSS
* { /* 好ましくないが取りあえずマージンとパディングをリセット */ margin: 0; padding: 0; } #slider_wrap { margin: 20px auto; width: 680px; /* 全体の幅 */ height: 125px; /* パネルの高さ + パディング */ padding: 20px; background: #EFEFEF; position: relative; /* 基点とするため相対配置に */ border: 1px solid #CCC; } #slider_prev { position: absolute; /* 絶対配置 */ top: 65px; left: 10px; cursor: pointer; } #slider_next { position: absolute; /* 絶対配置 */ top: 65px; right: 10px; cursor: pointer; } #slider { width: 100%; height: 100%; overflow: hidden; /* はみ出た部分を非表示に */ } #slider_inner ul.panel { width: 640px; height: 85px; padding: 20px; /* パネルの幅+パディング = 680px */ list-style-type: none; float: left; background: #999; /* 領域がわかりやすいように色づけ */ } #slider_inner ul.panel li { float: left; margin: 0 5px; display: inline; /* li をフロートさせるとIE6 ではずれるのでこの指定で回避 */ } #slider_inner ul.panel img { border: none; }
(注意)CSS の設定によっては「表示領域の横幅」にパディングも含める必要がある。$(‘#slider_wrap’).outerWidth() なども利用できるが、数値で指定した方が確実かもしれない。
但し、その場合パネル全体を格納する div 要素(id=”slider_inner”)の幅の算出にはパディングを含めるがパネルをスライドさせる距離ではパディング分を差し引かなければならなくなる可能性もある。CSS の設定によりこれらの値は変更しなければならない場合もあるので注意する。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ //表示領域の横幅(CSS の設定によってはパディングも含める必要がある) var slider_width = $('#slider_wrap').width(); var slider_inner$ = $('#slider_inner'); //パネル全体を格納する div 要素の幅を設定 slider_inner$.css('width', slider_width * $('#slider_inner ul.panel').size() + 'px'); //最後のパネルを先頭位置に移動 $('#slider_inner ul.panel:last').prependTo('#slider_inner'); //移動した分だけ左方向へずらす(★) slider_inner$.css('margin-left', '-' + slider_width + 'px'); //戻る」と「進む」ボタン var prev_next$ = $('#slider_next, #slider_prev'); $('#slider_prev').click(function(){ prev_next$.hide(); slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) + slider_width + 'px' }, 700, function(){ slider_inner$.css('margin-left', '-' + slider_width + 'px'); $('#slider_inner ul.panel:last').prependTo('#slider_inner'); prev_next$.show(); }); }); $('#slider_next').click(function(){ prev_next$.hide(); slider_inner$.stop().animate({ //「戻る」では加算したが「進む」では減算 marginLeft: parseInt(slider_inner$.css('margin-left'), 10) - slider_width + 'px' }, 700, //「戻る」では「prependTo」だが「進む」では「appendTo」 function(){ slider_inner$.css('margin-left', '-' + slider_width + 'px'); $('#slider_inner ul.panel:first').appendTo('#slider_inner'); prev_next$.show(); }); }); }); </script>
setInterval を利用して一定間隔(3秒)で自動的にスライドさせる。
カーソルがカルーセルの領域に入ると一時的にスライドを停止させ、ユーザーがクリックできるようにする。
「止める」ボタン(「止める」と「開始」を兼ねる)を追加。
<p id="stop">Stop</p>
CSS
#stop { cursor: pointer; background: #666; color: #FFF; border: 1px solid #999; width: 50px; height: 2em; text-align: center; line-height: 2em; }
jQuery に以下を追記。
var timer; //「止める」ボタンがクリックされたかどうか var is_stopped = false; var stop$ = $('#stop'); function start_carousel() { timer = setInterval(function(){ $('#slider_next').click(); },3000); stop$.text('Stop'); is_stopped = false; } function stop_carousel() { clearInterval(timer); stop$.text('Start'); is_stopped = true; } $('#slider_wrap').hover(function() { clearInterval(timer); },function() { //「止める」ボタンがクリックされていない場合のみ再開(マウスアウト) if(!is_stopped) { start_carousel(); } }); stop$.click(function(){ if(is_stopped) { start_carousel(); }else{ stop_carousel(); } }); //自動的に開始 start_carousel(); //念のため(不要?) $(window).unload(function(){ window.clearInterval(timer); });
このサンプルの場合1つのパネルに4つのサムネイルを表示しているが、サムネイルを1つ追加する場合を考えてみる。
最初に表示されるパネルに新しく追加したサムネイルを表示したい場合、全ての li 要素をずらす必要があるので更新が面倒になる可能性がある(数が多ければ多いほど)。
そこで、サムネイルは1つの ul 要素(id=”list”)の中に li 要素と記述して、jQuery でその構造を4つずつ(n 個ずつ)の li 要素を含む ul 要素に変更するようにして、その後でカルーセルパネル(スライドパネル)の表示の記述を行えば、前述のサンプルと同じ結果になり更新も簡単になる(と思う)。
HTML
<div id="slider_wrap"> <div id="slider"> <div id="slider_inner"> <ul id="list"> <li><a href="#"><img src="images/1.jpg" alt=""></a></li> <li><a href="#"><img src="images/2.jpg" alt=""></a></li> <li><a href="#"><img src="images/3.jpg" alt=""></a></li> <li><a href="#"><img src="images/4.jpg" alt=""></a></li> ・・・省略・・・ <li><a href="#"><img src="images/9.jpg" alt=""></a></li> <li><a href="#"><img src="images/10.jpg" alt=""></a></li> <li><a href="#"><img src="images/11.jpg" alt=""></a></li> <li><a href="#"><img src="images/12.jpg" alt=""></a></li> </ul> </div><!--end of #slider_inner--> </div><!--end of #slider--> </div><!--end of #slider_wrap-->
サムネイルの数(list_length)がパネルに表示する数(n)で割り切れれば簡単だが、そうでない場合を考慮しないとならない。
サムネイルの数(list_length)をパネルに表示する数(n)で割った余りが、最後のパネルに表示されるサムネイルの数なので、最後のパネルの余白の数は「n – list_length % n」になり、その分は <li></li> として表示するようにする。
パネルの数を算出「Math.ceil(list_length / n)」して、パネルごとに ul 要素(ul class=”panel”)を生成しそれに li 要素を移していく。
jQuery
jQuery(function($){ function reform_li(n) { var list$ = $('ul#list li'); var list_length = list$.length; //余白の数 var offset_li = n - list_length % n; if(list_length % n === 0) { offset_li = 0;} var is_offset = true; if(offset_li === 0) {is_offset = false; } //パネル(行)の数 var list_row_count = Math.ceil(list_length / n); var ul_panel; var current_list_length; for(var i = 0; i < list_row_count; i ++) { ul_panel = $('<ul class="panel"></ul>').prependTo('#slider_inner'); current_list_length = $('ul#list li').length + offset_li; for(var j = current_list_length - 1; j >= current_list_length - n; j--){ if(is_offset) { ul_panel.prepend($('<li></li>')); offset_li --; if(offset_li === 0) {is_offset = false; } }else{ ul_panel.prepend($('ul#list li').eq(j)); } } } $('ul#list').remove(); } });
パネルの数を表す画像(slider-icon.png, slider-icon-selected.png)を用意
それらを表示する領域の div 要素(id=”icon”)を追加
<div id="slider_wrap"> <p id="slider_prev"><img src="images/slider-prev.png" alt="prev"></p> <p id="slider_next"><img src="images/slider-next.png" alt="next"></p> <div id="slider"> <div id="slider_inner"> <ul class="panel"> <li><a href="#"><img src="images/1.jpg" alt=""></a></li> <li><a href="#"><img src="images/2.jpg" alt=""></a></li> <li><a href="#"><img src="images/3.jpg" alt=""></a></li> <li><a href="#"><img src="images/4.jpg" alt=""></a></li> </ul> ・・・省略・・・ <ul class="panel"> <li><a href="#"><img src="images/13.jpg" alt=""></a></li> <li><a href="#"><img src="images/14.jpg" alt=""></a></li> <li><a href="#"><img src="images/15.jpg" alt=""></a></li> <li><a href="#"><img src="images/16.jpg" alt=""></a></li> </ul> </div><!-- end of #slider_inner --> </div><!-- end of #slider --> <!-- 以下を追加--> <div id="icon"><a href="#"><img src="images/slider-icon.png" height="14" width="14" alt= ""></a></div> </div><!-- end of #slider_wrap -->
パネルの数を表す画像の領域とその中のリンク要素の CSS を以下のように設定
#icon { padding-top: 10px; width: 30px; margin: 0 auto; } #icon a { padding: 8px; }
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ //パネル(ul.panel)の数を「panel_count」に格納 var panel_count = $('#slider_inner ul.panel').length; //パネルの数を表す画像の領域の幅の初期値を「icon_width」に格納 var icon_width = $('#icon').width(); //パネルの数を表す画像は HTML に1つだけ記述してあるのでパネルの数分生成 if(panel_count > 1) { for(var i = 0; i < panel_count -1 ; i++) { $('#icon a:first').clone().appendTo('#icon'); } //「panel_count」を使ってパネルの数を表す画像の領域の幅を設定 $('#icon').css('width', icon_width * panel_count); } //パネルの数を表す画像のラップ集合を「icon_imgs」に格納 var icon_imgs = $('#icon img'); //パネルの数を表す画像のリンクのラップ集合を「icon_links」に格納 var icon_links = $('#icon a'); //現在表示されているパネルのインデックスを「current_panel」に格納し、初期値「0」を設定 var current_panel = 0; //現在表示されているパネルを表す画像を「slider-icon-selected.png」に設定 $(icon_imgs.get(current_panel)).attr('src', "images/slider-icon-selected.png"); //現在表示されているパネルを表す画像のクリックイベント icon_links.click(function(){ //画像をスライドさせるアニメーション中の場合は何もしない(位置がずれるため) if(is_animate) return false; var this$ = $(this); //クリックされたリンクのインデックスを「icon_index」に格納 var icon_index = icon_links.index(this$); //「icon_imgs」の全ての要素を調査して、現在表示されているパネルのインデックスを取得して「current_icon_index」に格納 var current_icon_index; icon_imgs.each(function(n) { if($(this).attr('src') == "images/slider-icon-selected.png") { current_icon_index = n; } }); //クリックされたリンクのインデックス「icon_index」と現在表示されているパネルのインデックス「current_icon_index」を比較 if(icon_index < current_icon_index){ //「icon_index」が小さければ、setInterval を使って click_prev() を「current_icon_index – icon_index」回実行 var count = 0; var timer = window.setInterval(function(){ if(count < current_icon_index - icon_index) { click_prev(400); count++; }else{ clearInterval(timer); } //setInterval の遅延時間は click_prev() のアニメーションの時間(400)より大きく設定 }, 500); }else{ var count = 0; var timer = window.setInterval(function(){ if(count < icon_index -current_icon_index ) { click_next(400); count++; }else{ clearInterval(timer); } }, 500); } return false; }); var slider_width = $('#slider_wrap').width(); var slider_inner$ = $('#slider_inner'); slider_inner$.css('width', slider_width * $('#slider_inner ul.panel').size() + 'px'); $('#slider_inner ul.panel:last').prependTo('#slider_inner'); slider_inner$.css('margin-left', '-' + slider_width + 'px'); var prev_next$ = $('#slider_next, #slider_prev'); var is_animate = false; //「戻る」ボタンをクリックした際の処理を関数にする //パネルを表す画像のクリックイベントの中で遅延時間を調整できるようにする function click_prev(speed) { is_animate = true; prev_next$.hide(); slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) + slider_width + 'px' }, speed, function(){ slider_inner$.css('margin-left', '-' + slider_width + 'px'); $('#slider_inner ul.panel:last').prependTo('#slider_inner'); prev_next$.show(); //現在表示されているパネルのインデックスを更新 if(current_panel > 0 ) { current_panel --; }else{ current_panel = panel_count -1; } icon_imgs.attr('src', "images/slider-icon.png"); //現在表示されているパネルに対応する画像を変更 $(icon_imgs.get(current_panel)).attr('src', "images/slider-icon-selected.png"); is_animate = false; }); } //「進む」ボタンをクリックした際の処理を関数にする //パネルを表す画像のクリックイベントの中で遅延時間を調整できるようにする function click_next(speed) { is_animate = true; prev_next$.hide(); slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) - slider_width + 'px' }, speed, function(){ slider_inner$.css('margin-left', '-' + slider_width + 'px'); $('#slider_inner ul.panel:first').appendTo('#slider_inner'); prev_next$.show(); //現在表示されているパネルのインデックスを更新 current_panel = (current_panel + 1) % panel_count; icon_imgs.attr('src', "images/slider-icon.png"); //現在表示されているパネルに対応する画像を変更 $(icon_imgs.get(current_panel)).attr('src', "images/slider-icon-selected.png"); is_animate = false; }); } $('#slider_prev').click(function(){ click_prev(700); }); $('#slider_next').click(function(){ click_next(700); }); }); </script>
前述のサンプルでは、パネルの数を表す画像をクリックした場合、少し動きがぎこちないので以下のように変更してみる。
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ //パネル(ul.panel)の数を「panel_count」に格納 var panel_count = $('#slider_inner ul.panel').length; //パネルの数を表す画像の領域の幅の初期値を「icon_width」に格納 var icon_width = $('#icon').width(); //パネルの数を表す画像は HTML に1つだけ記述してあるのでパネルの数分生成 if(panel_count > 1) { for(var i = 0; i < panel_count -1 ; i++) { $('#icon a:first').clone().appendTo('#icon'); } //「panel_count」を使ってパネルの数を表す画像の領域の幅を設定 $('#icon').css('width', icon_width * panel_count); } //パネルの数を表す画像のラップ集合を「icon_imgs」に格納 var icon_imgs = $('#icon img'); //パネルの数を表す画像のリンクのラップ集合を「icon_links」に格納 var icon_links = $('#icon a'); //現在表示されているパネルのインデックスを「current_panel」に格納し、初期値「0」を設定 var current_panel = 0; //現在表示されているパネルを表す画像を「slider-icon-selected.png」に設定 $(icon_imgs.get(current_panel)).attr('src', "images/slider-icon-selected.png"); var slider_width = $('#slider_wrap').width(); var slider_inner$ = $('#slider_inner'); slider_inner$.css('width', slider_width * $('#slider_inner ul.panel').size() + 'px'); $('#slider_inner ul.panel:last').prependTo('#slider_inner'); slider_inner$.css('margin-left', '-' + slider_width + 'px'); var prev_next$ = $('#slider_next, #slider_prev'); //現在表示されているパネルに対応する画像を変更とボタンを表示する処理 function setup() { //パネルに対応する画像を全て同じ画像にする(リセット) icon_imgs.attr('src', "images/slider-icon.png"); //現在表示されているパネルに対応する画像だけを変更 $(icon_imgs.get(current_panel)).attr('src', "images/slider-icon-selected.png"); } var default_speed = 700; //アニメーション中かどうかのフラグ var is_animate = false; var count = 0; function slide_panel(direction, repeat, speed) { is_animate = true; if(speed) { var speed = speed; }else{ var speed = default_speed; } if(direction == "prev") { var margin_left = parseInt(slider_inner$.css('margin-left'), 10) + slider_width + 'px'; }else{ var margin_left = parseInt(slider_inner$.css('margin-left'), 10) - slider_width + 'px'; } prev_next$.hide(); //パネルをスライドさせる slider_inner$.stop().animate({ marginLeft: margin_left }, speed, function(){ slider_inner$.css('margin-left', '-' + slider_width + 'px'); if(direction == "prev") { //最後のパネル(ul.panel:last)を先頭位置に移動(prependTo) $('#slider_inner ul.panel:last').prependTo('#slider_inner'); //現在表示されているパネルのインデックスを更新 current_panel = (panel_count + current_panel -1) % panel_count; }else{ //先頭のパネル(ul.panel:first)を最後に移動(appendTo) $('#slider_inner ul.panel:first').appendTo('#slider_inner'); //インデックスを更新 current_panel = (current_panel + 1) % panel_count; } setup(); prev_next$.show(); if(repeat == 1) { is_animate = false; count = 0; }else if(repeat == count) { is_animate = false; count = 0; } //繰り返し(再帰) if(repeat > 1) { slide_panel(direction, repeat -1, speed); count ++; } }); } $('#slider_prev').click(function(){ slide_panel('prev', 1, 500); }); $('#slider_next').click(function(){ slide_panel('next', 1, 500) }); //現在表示されているパネルを表す画像のクリックイベント icon_links.click(function(){ //画像をスライドさせるアニメーション中の場合は何もしない(位置がずれるため) if(is_animate) return false; var this$ = $(this); //クリックされたリンクのインデックスを「icon_index」に格納 var icon_index = icon_links.index(this$); //「icon_imgs」の全ての要素を調査して、現在表示されているパネルのインデックスを取得して「current_icon_index」に格納 var current_icon_index; icon_imgs.each(function(n) { if($(this).attr('src') == "images/slider-icon-selected.png") { current_icon_index = n; } }); //インデックスの差分(絶対値)を取得 var delta = Math.abs(icon_index - current_icon_index); //逆方向への移動距離を算出するための値 var alpha = panel_count - delta; //クリックされたリンクのインデックス「icon_index」と現在表示されているパネルのインデックス「current_icon_index」を比較 if(icon_index < current_icon_index){ //差分が写真の数の半分より大きい場合(どちら側へ移動するかを決めるため) if(delta > panel_count / 2) { slide_panel('next', alpha, 800); }else{ slide_panel('prev', delta, 800); } }else{ if(delta > panel_count / 2) { slide_panel('prev', alpha, 800); }else{ slide_panel('next', delta, 800); } } return false; }); }); </script>
カルーセルパネルのサムネイル画像をクリックすると、それに対応するメインの画像を表示するようにする。
メインの画像を表示する領域(id=”main_photo”)を追加。
HTML
<div id="main_photo"> <img src="images/photos/P1000812.jpg" alt=""> </div>
#main_photo 及びその中の img 要素はスライドショーで使いやすいように設定。
「overflow: hidden」はメインの画像をスライドで表示する場合に必要。
CSS
#main_photo { position: relative; margin: 0 auto; width: 680px; height: 383px; border: 3px solid #CCC; overflow: hidden; } #main_photo img { position: absolute; }
$('.panel li a').click(function() { var img$ = $(this).find('img'); var src = img$.attr('src').replace(/thumbnails/, 'photos'); var alt = img$.attr('alt'); $('#main_photo img').before('<img src="' + src + '" alt="' + alt + '">'); $('#main_photo img:last').fadeOut(400, function() { $(this).remove(); }); return false; });
クロスフェードではなく、メインの画像をスライドさせて表示する例。
基本的にはクロスフェードと同じ。fadeOut() の代わりに animate() でスライドさせる。
$('.panel li a').click(function() { var img$ = $(this).find('img'); var src = img$.attr('src').replace(/thumbnails/, 'photos'); var alt = img$.attr('alt'); $('#main_photo img').before('<img src="' + src + '" alt="' + alt + '">'); $('#main_photo img:last').stop().animate({ marginLeft: '-680px' }, 600, function(){ $(this).remove(); }); return false; });
サンプル2-3では、元の画像がスライドして、その下に新しい画像が表示されるが、以下は新しい画像がスライドして上に表示される例。
$('.panel li a').click(function() { var img$ = $(this).find('img'); var src = img$.attr('src').replace(/thumbnails/, 'photos'); var alt = img$.attr('alt'); var new_img$ = $('<img src="' + src + '" alt="' + alt + '">').css('left', '680px'); new_img$.insertAfter('#main_photo img').animate({ left: 0 }, 600, function() { $('#main_photo img:first').remove() }); return false; });
パネルをスライドさせるのではなく、画像1枚分スライドさせる場合。
HTML
<div id="slider_wrap"> <p id="slider_prev"><img src="images/slider-prev.png" height="30" width="20" alt="previous"></p> <p id="slider_next"><img src="images/slider-next.png" height="30" width="20" alt="next"></p> <div id="slider"> <div id="slider_inner"> <ul id="photo_list"> <li><a href="#"><img src="images/1.jpg" alt=""></a></li> <li><a href="#"><img src="images/2.jpg" alt=""></a></li> <li><a href="#"><img src="images/3.jpg" alt=""></a></li> <li><a href="#"><img src="images/4.jpg" alt=""></a></li> ・・・省略・・・ <li><a href="#"><img src="images/10.jpg" alt=""></a></li> <li><a href="#"><img src="images/11.jpg" alt=""></a></li> <li><a href="#"><img src="images/12.jpg" alt=""></a></li> </ul> </div><!-- end of #slider_inner --> </div><!-- end of #slider --> </div><!-- end of #slider_wrap --> <p id="stop">Stop</p>
CSS
#slider_wrap { margin: 20px auto; width: 700px; /* 変更 */ height: 125px; padding: 20px; background: #EFEFEF; position: relative; border: 1px solid #CCC; } #slider_prev { position: absolute; top: 65px; left: -10px; /* 変更 */ cursor: pointer; } #slider_next { position: absolute; top: 65px; right: -10px; /* 変更 */ cursor: pointer; } #slider { width: 100%; height: 100%; overflow: hidden; } #photo_list { /*width: 640px; 幅は指定しない*/ height: 85px; padding: 20px 10px; /* 変更 */ list-style-type: none; float: left; background: #999; } #photo_list li { float: left; margin: 0 10px; /* 変更 */ display: inline; } #photo_list img { border: none; } #stop { cursor: pointer; background: #666; color: #FFF; border: 1px solid #999; width: 50px; height: 2em; text-align: center; line-height: 2em; margin-left: 40px; }
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var photo_list$ = $('#photo_list'); var li$ = $('#photo_list li'); var li_count = li$.length; var li_width = li$.width() + parseInt(li$.css('margin-left'), 10) + parseInt(li$.css('margin-right'), 10); var ul_padding = parseInt(photo_list$.css('padding-left') , 10) + parseInt(photo_list$.css('padding-right') , 10); var slider_inner$ = $('#slider_inner'); //#slider_inner の幅は「 li 要素の幅(マージンを含む) X その個数」と ul 要素のパディングの合計 slider_inner$.css('width', (li_width * li_count + ul_padding) + 'px'); //最後の画像(#photo_list li:last)を ul 要素の先頭位置に移動(prependTo) $('#photo_list li:last').prependTo(photo_list$); //slider_inner を上記で移動した分だけ左方向へずらす slider_inner$.css('margin-left', '-' + li_width + 'px'); $('#slider_prev').click(function(){ slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) + li_width + 'px' }, 500, function(){ slider_inner$.css('margin-left', '-' + li_width + 'px'); $('#photo_list li:last').prependTo(photo_list$); }); }); $('#slider_next').click(function(){ slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) - li_width + 'px' }, 500, function(){ slider_inner$.css('margin-left', '-' + li_width + 'px'); $('#photo_list li:first').appendTo(photo_list$); }); }); var timer; var is_stopped = false; var stop$ = $('#stop'); var next_prev$ = $('#slider_next, #slider_prev'); function start_carousel() { timer = setInterval(function(){ $('#slider_next').click(); },1500); stop$.text('Stop'); is_stopped = false; } function stop_carousel() { clearInterval(timer); stop$.text('Start'); is_stopped = true; } $('#slider_wrap').hover(function() { clearInterval(timer); next_prev$.show(); },function() { if(!is_stopped) { start_carousel(); next_prev$.hide(); } }); stop$.click(function(){ if(is_stopped) { start_carousel(); next_prev$.hide(); }else{ stop_carousel(); next_prev$.show(); } }); //「戻る」と「進む」ボタンは非表示に next_prev$.hide(); //自動的にスタートするように設定 start_carousel(); //念のため(不要?) $(window).unload(function(){ window.clearInterval(timer); }); }); </script>
前述(サンプル3)の場合、1つの ul 要素の中に全てのサムネイル画像を配置したが、何らかの理由で「サンプル1」のようなパネルの構造を使う場合。
HTML と CSS はサンプル1とほぼ同じ。
例えば、「進む(Next)」の方向へ1つ移動した場合は「cell_position」は 1、「pos」は 1。
この時「戻る(Prev)」の方向へ1つ移動すると「cell_position」は 0、「pos」は 0 になるが、この場合はパネルの移動を行わない。「pos」の値が「-4 」または「4 」の場合のみ、パネルの移動を行う。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ //表示領域の横幅 var slider_width = $('#slider_wrap').width() ; var slider_inner$ = $('#slider_inner'); var panel$ = $('#slider_inner ul.panel'); var panel_size = panel$.size(); //パネル全体を格納する div 要素の幅を設定 slider_inner$.css('width', slider_width * panel_size + 'px'); //最後のパネルを先頭位置に移動 $('#slider_inner ul.panel:last').prependTo('#slider_inner'); //移動した分だけ左方向へずらす slider_inner$.css('margin-left', '-' + slider_width + 'px'); //戻る」と「進む」ボタン var prev_next$ = $('#slider_next, #slider_prev'); //サムネイルの横幅 var cell$ = $('ul.panel li'); var cell_width = cell$.width() + parseInt(cell$.css('margin-left'), 10) * 2; //パネル1枚に表示されているサムネイルの数 var cell_per_panel = $('ul.panel:first li').length; //パネルの左端のサムネイルのインデックス var cell_position = 0; //表示されているパネルの移動量(パネルを移動させるかを判定するために使用) var pos = 0; //パネルをサムネイルの幅だけ動かす関数 function move_cell(direction) { prev_next$.hide(); if(direction == 'prev') { //パネルをサムネイルの幅だけ動かす slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) + cell_width + 'px' }, 700, function(){ cell_position = (cell_position - 1 + cell_per_panel) % cell_per_panel; pos --; console.log('cell: ' + cell_position + ' pos: ' + pos); if(cell_position == 0 && pos == -4 ) { //パネルの位置を調整する reset_panel_position(direction); } prev_next$.show(); }); }else{ slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) - cell_width + 'px' }, 700, function(){ cell_position = (cell_position + 1) % cell_per_panel; pos ++; console.log('cell: ' + cell_position + ' pos: ' + pos); if(cell_position == 0 && pos == 4 ) { reset_panel_position(direction); } prev_next$.show(); }); } } //パネルの位置を調整する関数 function reset_panel_position(direction) { if(direction == 'prev'){ //左マージンをリセット slider_inner$.css('margin-left', '-' + slider_width + 'px'); //最後のパネルを先頭へ移動 $('#slider_inner ul.panel:last').prependTo('#slider_inner'); }else{ //左マージンをリセット slider_inner$.css('margin-left', '-' + slider_width + 'px'); //先頭のパネルを最後へ移動 $('#slider_inner ul.panel:first').appendTo('#slider_inner'); } //pos をリセット pos = 0; } $('#slider_prev').click(function(){ move_cell('prev') ; }); $('#slider_next').click(function(){ move_cell('next') ; }); var timer; var is_stopped = false; var next_prev$ = $('#slider_next, #slider_prev'); function start_carousel() { timer = setInterval(function(){ $('#slider_next').click(); },1500); $('#stop').text('Stop'); is_stopped = false; prev_next$.hide(); } function stop_carousel() { clearInterval(timer); $('#stop').text('Start'); is_stopped = true; prev_next$.show(); } $('#slider_wrap').hover(function() { clearInterval(timer); next_prev$.show(); },function() { if(!is_stopped) { start_carousel(); next_prev$.hide(); } }); $('#stop').click(function(){ if(is_stopped) { start_carousel(); }else{ stop_carousel(); } }); prev_next$.hide(); start_carousel(); $(window).unload(function(){ window.clearInterval(timer); }); }); </script>
前述(サンプル3-2)に、パネルをスライドする操作を追加してみる。
HTML では以下を追加。
<div id="control"> <p id="panel_prev"><<</p> <p id="stop">Stop</p> <p id="panel_next">>></p></div> </div>
CSS では以下を追加。
#control { width: 100%; position: relative; } #panel_prev, #panel_next { cursor: pointer; background: #CCC; color: #666; border: 1px solid #999; width: 50px; height: 2em; text-align: center; line-height: 2em; } #panel_prev { position: absolute; left: 30px; top: 0; } #panel_next { position: absolute; right: 30px; top: 0; }
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ //表示領域の横幅 var slider_width = $('#slider_wrap').width() ; var slider_inner$ = $('#slider_inner'); var panel$ = $('#slider_inner ul.panel'); var panel_size = panel$.size(); //パネル全体を格納する div 要素の幅を設定 slider_inner$.css('width', slider_width * panel_size + 'px'); //最後のパネルを先頭位置に移動 $('#slider_inner ul.panel:last').prependTo('#slider_inner'); //移動した分だけ左方向へずらす slider_inner$.css('margin-left', '-' + slider_width + 'px'); //戻る」と「進む」ボタン var prev_next$ = $('#slider_next, #slider_prev'); //サムネイルの横幅 var cell$ = $('ul.panel li'); var cell_width = cell$.width() + parseInt(cell$.css('margin-left'), 10) * 2; //パネル1枚に表示されているサムネイルの数 var cell_per_panel = $('ul.panel:first li').length; var panel_prev_next$ = $('#panel_prev, #panel_next'); function hide_control() { prev_next$.hide(); panel_prev_next$.hide(); } function show_control() { prev_next$.show(); panel_prev_next$.show(); } var cell_position = 0; var pos = 0; function move_cell(direction) { prev_next$.hide(); if(direction == 'prev') { slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) + cell_width + 'px' }, 700, function(){ cell_position = (cell_position - 1 + cell_per_panel) % cell_per_panel; pos --; console.log('pos : ' + pos); if(cell_position == 0 && pos == -4 ) { reset_panel_position(direction); } prev_next$.show(); }); }else{ slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) - cell_width + 'px' }, 700, function(){ cell_position = (cell_position + 1) % cell_per_panel; pos ++; console.log('pos : ' + pos); if(cell_position == 0 && pos == 4 ) { reset_panel_position(direction); } prev_next$.show(); }); } } //パネルの位置を調整する関数 function reset_panel_position(direction) { if(direction == 'prev'){ //左マージンをリセット slider_inner$.css('margin-left', '-' + slider_width + 'px'); //最後のパネルを先頭へ移動 $('#slider_inner ul.panel:last').prependTo('#slider_inner'); }else{ //左マージンをリセット slider_inner$.css('margin-left', '-' + slider_width + 'px'); //先頭のパネルを最後へ移動 $('#slider_inner ul.panel:first').appendTo('#slider_inner'); } //pos をリセット pos = 0; console.log('**Reset_Panel** pos: ' + pos); } //パネルをスライドさせる関数 function slide_panel(direction) { hide_control() if(direction == 'prev') { if(cell_position != 0) { slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) + cell_width * cell_position + 'px' }, 600, function(){ cell_position = 0; //pos の値が 0 以下の場合はパネルの位置を移動 if(pos <= 0) { reset_panel_position(direction); } //pos の値が 0 より大きい場合はパネルの位置はそのままで、pos のみリセット pos = 0; show_control(); }); }else{ slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) + slider_width + 'px' }, 700, function(){ reset_panel_position(direction); show_control(); }); } }else{ if(cell_position != 0) { slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) - cell_width * (cell_per_panel - cell_position) + 'px' }, 600, function(){ cell_position = 0; //pos の値が 0 以上の場合はパネルの位置を移動 if(pos >= 0) { reset_panel_position(direction); } //pos の値が 0 未満の場合はパネルの位置はそのままで、pos のみリセット pos = 0; show_control(); }); }else{ slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) - slider_width + 'px' }, 700, function(){ reset_panel_position(direction); show_control(); }); } } } $('#slider_prev').click(function(){ move_cell('prev') ; }); $('#slider_next').click(function(){ move_cell('next') ; }); $('#panel_prev').click(function(){ slide_panel('prev'); }); $('#panel_next').click(function(){ slide_panel('next'); }); var timer; var is_stopped = false; var next_prev$ = $('#slider_next, #slider_prev'); function start_carousel() { timer = setInterval(function(){ $('#slider_next').click(); },1500); $('#stop').text('Stop'); is_stopped = false; hide_control() } function stop_carousel() { clearInterval(timer); $('#stop').text('Start'); is_stopped = true; show_control() } $('#slider_wrap').hover(function() { clearInterval(timer); next_prev$.show(); },function() { if(!is_stopped) { start_carousel(); next_prev$.hide(); } }); $('#stop').click(function(){ if(is_stopped) { start_carousel(); }else{ stop_carousel(); } }); hide_control() start_carousel(); $(window).unload(function(){ window.clearInterval(timer); }); }); </script>
「サンプル3」の画像1枚分スライドさせるもので大きな画像を表示してみる。
CSS も大きな画像を表示するためにそれぞれの要素の高さと幅や位置を変更するだけ。
CSS
#slider_wrap { margin: 20px auto; width: 720px; /*変更*/ height: 423px; /*変更*/ padding: 20px; background: #EFEFEF; position: relative; border: 1px solid #CCC; } #slider_prev { position: absolute; top: 205px; /*変更*/ left: 10px; cursor: pointer; } #slider_next { position: absolute; top: 205px; /*変更*/ right: 10px; cursor: pointer; } #slider { width: 100%; height: 100%; overflow: hidden; } #photo_list { height: 383px; /*変更*/ padding: 20px; list-style-type: none; float: left; background: #999; } #photo_list li { float: left; margin-right: 20px; /*変更*/ display: inline; } #photo_list img { border: none; } #stop { cursor: pointer; background: #666; color: #FFF; border: 1px solid #999; width: 50px; height: 2em; text-align: center; line-height: 2em; margin-left: 40px; }
jQuery も前のサンプルとほぼ同じ。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var photo_list$ = $('#photo_list'); var li$ = $('#photo_list li'); var li_count = li$.length; var li_width = li$.width() + parseInt(li$.css('margin-left'), 10) + parseInt(li$.css('margin-right'), 10); var ul_padding = parseInt(photo_list$.css('padding-left') , 10) + parseInt(photo_list$.css('padding-right') , 10); var slider_inner$ = $('#slider_inner'); slider_inner$.css('width', (li_width * li_count + ul_padding) + 'px'); $('#photo_list li:last').prependTo(photo_list$); slider_inner$.css('margin-left', '-' + li_width + 'px'); $('#slider_prev').click(function(){ slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) + li_width + 'px' }, 800, function(){ slider_inner$.css('margin-left', '-' + li_width + 'px'); $('#photo_list li:last').prependTo(photo_list$); }); }); $('#slider_next').click(function(){ slider_inner$.stop().animate({ marginLeft: parseInt(slider_inner$.css('margin-left'), 10) - li_width + 'px' }, 800, function(){ slider_inner$.css('margin-left', '-' + li_width + 'px'); $('#photo_list li:first').appendTo(photo_list$); }); }); var timer; var is_stopped = false; var next_prev$ = $('#slider_next, #slider_prev'); function start_carousel() { timer = setInterval(function(){ $('#slider_next').click(); },2500); $('#stop').text('Stop'); is_stopped = false; } function stop_carousel() { clearInterval(timer); $('#stop').text('Start'); is_stopped = true; } $('#slider_wrap').hover(function() { clearInterval(timer); next_prev$.show(); },function() { if(!is_stopped) { start_carousel(); next_prev$.hide(); } }); $('#stop').click(function(){ if(is_stopped) { start_carousel(); next_prev$.hide(); }else{ stop_carousel(); next_prev$.show(); } }); next_prev$.hide(); start_carousel(); //念のため(不要?) $(window).unload(function(){ window.clearInterval(timer); }); }); </script>
前述のカルーセルの場合、最低でもパネルの数は3つ必要で2つ以下の場合はうまく機能しない。
カルーセルではなく(1周すると元のパネルに戻るのではなく)、単に「前へ」または「次へ」の方向にスライドさせるようにする。
HTML と CSS は「サンプル1」と同じ。
jQuery では現在どのパネル(#slider_inner ul.panel)が表示されているかにより、「前へ」または「次へ」のボタンを表示するかどうかを判定して表示。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ //パネルの総数 var panel_count = $('#slider_inner ul.panel').length; var slider_width = $('#slider_wrap').width(); //パネル全体を格納する div 要素の幅を「表示領域の横幅 X パネルの数」に設定 var slider_inner$ = $('#slider_inner'); slider_inner$.css('width', slider_width * panel_count + 'px'); //現在表示されているパネルのインデックス(初期化) var current_panel = 0; var prev$ = $('#slider_prev'); var next$ = $('#slider_next'); var prev_next$ = $('#slider_prev, #slider_next'); //パネルのインデックスにより「戻る」と「進む」を表示するかどうかを判定 function show_button() { if(current_panel <= 0 ) { prev$.css('visibility', 'hidden'); }else{ prev$.css('visibility', 'visible'); } if(current_panel >= panel_count-1) { next$.css('visibility', 'hidden'); }else{ next$.css('visibility', 'visible'); } } show_button(); prev$.click(function(){ prev_next$.hide(); var margin_left = parseInt(slider_inner$.css('margin-left'), 10) + slider_width; slider_inner$.stop().animate({ marginLeft: margin_left + 'px' }, 700, function(){ prev_next$.show(); if(current_panel > 0 ) { current_panel--; }else{ current_panel = panel_count -1; } show_button(); }); }); next$.click(function(){ prev_next$.hide(); var margin_left = parseInt(slider_inner$.css('margin-left'), 10) - slider_width; slider_inner$.stop().animate({ marginLeft: margin_left + 'px' }, 700, function(){ prev_next$.show(); current_panel = (current_panel + 1) % panel_count; show_button(); }); }); }); </script>
サンプル5のように位置により「前へ」または「次へ」のボタンの表示を変更するのではなく、以下のようにする。
このため、どのパネルが表示されているかがわかりやすいように、それを表す画像を追加。
HTML と CSS はサンプル2と同じ。
jQuery では重複する記述が増えるので、パネルをスライドさせる処理を「animate_panel()」、「パネルの数を表す画像のリンク」の背景画像を設定する処理を「icon_setup()」という関数にしておく。
また、「パネルの数を表す画像のリンク」をクリックした場合の処理は、現在表示されているパネルとクリックされた「パネルの数を表す画像のリンク」の位置関係からスライドさせる量を調整。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ //パネルの総数 var panel_count = $('#slider_inner ul.panel').length; var slider_width = $('#slider_wrap').width(); //パネル全体を格納する div 要素の幅を「表示領域の横幅 X パネルの数」に設定 $('#slider_inner').css('width', slider_width * panel_count + 'px'); //現在表示されているパネルのインデックス(初期化) var current_panel = 0; var icon_width = $('#icon').width(); //どのパネルが表示されているかを示す画像要素を生成 if(panel_count > 1) { for(var i = 0; i < panel_count -1 ; i++) { $('#icon a:first').clone().appendTo('#icon'); } $('#icon').css('width', icon_width * panel_count); } var icon_imgs = $('#icon img'); var icon_links = $('#icon a'); //現在表示されているパネルに対応する画像を変更(異なる色にする) $(icon_imgs.get(current_panel)).attr('src', "images/slider-icon-selected.png"); var prev_next$ = $('#slider_prev, #slider_next'); var slider_inner$ = $('#slider_inner'); var default_speed = 700; //パネルをスライドさせるアニメーション function animate_panel(margin_left, speed) { if(speed) { var speed = speed; }else{ var speed = default_speed; } prev_next$.hide(); slider_inner$.stop().animate({ marginLeft: margin_left + 'px' }, speed, function(){ prev_next$.show(); }); } //現在表示されているパネルに対応する画像を変更する処理 function icon_setup() { icon_imgs.attr('src', "images/slider-icon.png"); $(icon_imgs.get(current_panel)).attr('src', "images/slider-icon-selected.png"); } icon_links.click(function(){ var this$ = $(this); //クリックされた画像のインデックスを取得 var icon_index = icon_links.index(this$); //現在のパネルを示す画像のインデックスを取得 var current_icon_index; icon_imgs.each(function(n) { if($(this).attr('src') == "images/slider-icon-selected.png") { current_icon_index = n; } }); current_panel = icon_index; icon_setup(); //インデックスの差分を取得 var delta = Math.abs(icon_index - current_icon_index); //それぞれのインデックスを比較して処理を実行 if(icon_index < current_icon_index){ var margin_left = parseInt($('#slider_inner').css('margin-left'), 10) + slider_width * delta; animate_panel(margin_left); }else{ var margin_left = parseInt($('#slider_inner').css('margin-left'), 10) - slider_width * delta; animate_panel(margin_left); } return false; }); $('#slider_prev').click(function(){ if(current_panel > 0) { current_panel --; icon_setup(); var margin_left = parseInt($('#slider_inner').css('margin-left'), 10) + slider_width; animate_panel(margin_left); }else{ current_panel = panel_count -1; icon_setup(); var margin_left = parseInt($('#slider_inner').css('margin-left'), 10) - (slider_width * (panel_count -1)); animate_panel(margin_left); } }); $('#slider_next').click(function(){ if(current_panel < panel_count - 1) { var margin_left = parseInt($('#slider_inner').css('margin-left'), 10) - slider_width; animate_panel(margin_left); }else{ var margin_left = parseInt($('#slider_inner').css('margin-left'), 10) + (slider_width * (panel_count -1)); animate_panel(margin_left); } current_panel = (current_panel + 1) % panel_count; icon_setup(); }); }); </script>
HTML と CSS はサンプル3と同じ。。
jQuery ではサンプル5と同じように画像の位置により「前へ」または「次へ」のボタンを表示するかどうかを判定して表示。(サンプル5の場合はパネルの位置で判定)
また、「先頭」と「最後」というボタンを作成し、その位置へスライドするようにする。
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var photo_list$ = $('#photo_list'); var li$ = $('#photo_list li'); var li_count = li$.length; var li_width = li$.width() + parseInt(li$.css('margin-left'), 10) + parseInt(li$.css('margin-right'), 10); var ul_padding = parseInt(photo_list$.css('padding-left') , 10) + parseInt(photo_list$.css('padding-right') , 10); var slider_inner$ = $('#slider_inner'); slider_inner$.css('width', (li_width * li_count + ul_padding) + 'px'); //現在一番左に表示されている画像のインデックス(初期化) var current_image = 0; //画像のインデックスにより「戻る」と「進む」を表示するかどうかを判定 var prev$ = $('#slider_prev'); var next$ = $('#slider_next'); function show_button() { if(current_image <= 0 ) { prev$.css('visibility', 'hidden'); }else{ prev$.css('visibility', 'visible'); } if(current_image == li_count-4) { next$.css('visibility', 'hidden'); }else{ next$.css('visibility', 'visible'); } } show_button(); var prev_next$ = $('#slider_prev, #slider_next'); var default_speed = 500; //パネルをスライドさせるアニメーション function animate_panel(margin_left, speed) { if(speed) { var speed = speed; }else{ var speed = default_speed; } prev_next$.hide(); slider_inner$.stop().animate({ marginLeft: margin_left + 'px' }, speed, function(){ prev_next$.show(); }); } //現在表示されているパネルに対応する画像を変更する処理 function icon_setup() { icon_imgs.attr('src', "images/slider-icon.png"); $(icon_imgs.get(current_panel)).attr('src', "images/slider-icon-selected.png"); } $('#slider_prev').click(function(){ if(current_image > 0 ) { animate_panel(parseInt(slider_inner$.css('margin-left'), 10) + li_width); current_image --; show_button(); }else{ show_button(); } }); $('#slider_next').click(function(){ if(current_image < li_count -4) { animate_panel(parseInt(slider_inner$.css('margin-left'), 10) - li_width); current_image ++; show_button(); }else{ show_button(); } }); $('#last').click(function(){ animate_panel(li_width * (li_count - 4) * -1); current_image = li_count -4; show_button(); }); $('#top').click(function(){ animate_panel(0); current_image = 0; show_button(); }); }); </script>
サンプル4と同じように大きな画像をスライドさせる。
HTML と CSS はサンプル4とほぼ同じ(「先頭」と「最後」というボタンを追加)。
jQuery はサンプル6とほぼ同じ。但し、パネルではなく画像1枚をスライドさせるので、現在表示されている画像のインデックス(current_image)での比較が多少異なる。
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var photo_list$ = $('#photo_list'); var li$ = $('#photo_list li'); var li_count = li$.length; var li_width = li$.width() + parseInt(li$.css('margin-left'), 10) + parseInt(li$.css('margin-right'), 10); var ul_padding = parseInt(photo_list$.css('padding-left') , 10) + parseInt(photo_list$.css('padding-right') , 10); var slider_inner$ = $('#slider_inner'); slider_inner$.css('width', (li_width * li_count + ul_padding) + 'px'); //現在表示されている画像のインデックス(初期化) var current_image = 0; //画像のインデックスにより「戻る」と「進む」を表示するかどうかを判定 var prev$ = $('#slider_prev'); var next$ = $('#slider_next'); function show_button() { if(current_image <= 0 ) { prev$.css('visibility', 'hidden'); }else{ prev$.css('visibility', 'visible'); } if(current_image == li_count-1) { next$.css('visibility', 'hidden'); }else{ next$.css('visibility', 'visible'); } } show_button(); var prev_next$ = $('#slider_prev, #slider_next'); var default_speed = 500; //パネルをスライドさせるアニメーション function animate_panel(margin_left, speed) { if(speed) { var speed = speed; }else{ var speed = default_speed; } prev_next$.hide(); slider_inner$.stop().animate({ marginLeft: margin_left + 'px' }, speed, function(){ prev_next$.show(); }); } $('#slider_prev').click(function(){ if(current_image > 0 ) { animate_panel(parseInt(slider_inner$.css('margin-left'), 10) + li_width); current_image --; show_button(); }else{ show_button(); } }); $('#slider_next').click(function(){ if(current_image < li_count -1) { animate_panel(parseInt(slider_inner$.css('margin-left'), 10) - li_width); current_image ++; show_button(); }else{ show_button(); } }); $('#last').click(function(){ animate_panel(li_width * (li_count - 1) * -1, 1200); current_image = li_count -1; show_button(); }); $('#top').click(function(){ animate_panel(0, 1200); current_image = 0; show_button(); }); }); </script>
今までの方法を組み合わせたもの。
HTML と CSS はサンプル7とほぼ同じ(どの画像が表示されているかを示す画像を追加)。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var photo_list$ = $('#photo_list'); var li$ = $('#photo_list li'); var li_count = li$.length; var li_width = li$.width() + parseInt(li$.css('margin-left'), 10) + parseInt(li$.css('margin-right'), 10); var ul_padding = parseInt(photo_list$.css('padding-left') , 10) + parseInt(photo_list$.css('padding-right') , 10); var slider_inner$ = $('#slider_inner'); slider_inner$.css('width', (li_width * li_count + ul_padding) + 'px'); //画像のインデックスにより「戻る」と「進む」を表示するかどうかを判定 var prev$ = $('#slider_prev'); var next$ = $('#slider_next'); function show_button() { if(current_image <= 0 ) { prev$.css('visibility', 'hidden'); }else{ prev$.css('visibility', 'visible'); } if(current_image == li_count-1) { next$.css('visibility', 'hidden'); }else{ next$.css('visibility', 'visible'); } } //現在表示されている画像のインデックス(初期化) var current_image = 0; var icon_width = $('#icon').width(); if(li_count > 1) { for(var i = 0; i < li_count -1 ; i++) { $('#icon a:first').clone().appendTo('#icon'); } $('#icon').css('width', icon_width * li_count); } var icon_imgs = $('#icon img'); var icon_links = $('#icon a'); $(icon_imgs.get(current_image)).attr('src', "images/slider-icon-selected.png"); var prev_next$ = $('#slider_prev, #slider_next'); var default_speed = 500; //コールバックで繰り返し使用する関数(パネルをスライドさせるアニメーション) function animate_panel(margin_left, speed) { if(speed) { var speed = speed; }else{ var speed = default_speed; } prev_next$.hide(); slider_inner$.stop().animate({ marginLeft: margin_left + 'px' }, speed, function(){ prev_next$.show(); }); } //現在表示されているパネルに対応する画像を変更とボタンを表示する処理 function setup() { icon_imgs.attr('src', "images/slider-icon.png"); $(icon_imgs.get(current_image)).attr('src', "images/slider-icon-selected.png"); show_button(); } icon_links.click(function(){ var this$ = $(this); //クリックされた画像のインデックスを取得 var icon_index = icon_links.index(this$); //現在のパネルを示す画像のインデックスを取得 var current_icon_index; icon_imgs.each(function(n) { if($(this).attr('src') == "images/slider-icon-selected.png") { current_icon_index = n; } }); //インデックスの差分を取得 var delta = Math.abs(icon_index - current_icon_index); //それぞれのインデックスを比較して処理を実行 if(icon_index < current_icon_index){ animate_panel(parseInt($('#slider_inner').css('margin-left'), 10) + li_width * delta, 700); current_image -= delta; setup(); }else{ animate_panel(parseInt($('#slider_inner').css('margin-left'), 10) - li_width * delta, 700); current_image += delta; setup(); } return false; }); $('#slider_prev').click(function(){ if(current_image > 0 ) { animate_panel(parseInt(slider_inner$.css('margin-left'), 10) + li_width, 500); current_image --; setup(); }else{ show_button(); } }); $('#slider_next').click(function(){ if(current_image < li_count -1) { animate_panel(parseInt(slider_inner$.css('margin-left'), 10) - li_width, 500); current_image ++; setup(); }else{ show_button(); } }); $('#last').click(function(){ animate_panel(li_width * (li_count - 1) * -1, 2000); current_image = li_count -1; setup(); }); $('#top').click(function(){ animate_panel(0, 2000); current_image = 0; setup(); }); //初期状態のボタンの表示 show_button(); }); </script>