jQueryを使ってのレスポンシブに対応したスライドショーを実装するいくつかのパターンを紹介してきましたが、サムネイルも何もなしでただ画像(コンテンツ要素)がクロスフェードするだけのシンプルなスライドショーのレスポンシブに対応したパターンの要望を多くいただいたので、試しに作ってみたのを紹介してみます。
jQueryでレスポンシブ対応のシンプルなクロスフェードビューアーを作る方法
レスポンシブ動作はブラウザ枠を目いっぱいにするタイプなので、まずは別枠表示で動作サンプルから。
「jQueryでレスポンシブ対応のシンプルなクロスフェードビューアーを作る方法」サンプルを別枠で表示
サンプルでは6枚の画像を自動でクロスフェードで切り替え、最大幅を「800px」最小幅を「320px」としてブラウザ幅によってスライドショー部分が拡大縮小します。(どちらの値も変更可)
簡単な動作仕様については以上になります。
全体構成についてまずはHTMLから。
◆HTML <div class="viewer"> <ul> <li><a href="#1"><img src="img/photo1.jpg" alt=""></a></li> <li><a href="#2"><img src="img/photo2.jpg" alt=""></a></li> <li><a href="#3"><img src="img/photo3.jpg" alt=""></a></li> <li><a href="#4"><img src="img/photo4.jpg" alt=""></a></li> <li><a href="#5"><img src="img/photo5.jpg" alt=""></a></li> <li><a href="#6"><img src="img/photo6.jpg" alt=""></a></li> </ul> </div><!--/.viewer-->
クラスやIDを付けた全体を囲う任意のブロック要素「.viewer」の中に<ul>リストを使って画像を並べます。
(画像に対して<a>タグでリンクを張ってありますがリンクする必要がない場合はこのタグは不要です。)
サンプルでは画像を6つにしていますが、これを増減させるには単純に<li>の数をそれぞれ同じ個数増減するだけです。
これに対してCSSは以下の様になります。
◆CSS /* .viewer ------------------------- */ .viewer { margin: 0 auto; width: 100%; position: relative; overflow: hidden; } .viewer ul { width: 100%; overflow: hidden; position: relative; } .viewer ul li { top: 0; left: 0; width: 100%; position: absolute; } .viewer ul li img { width: 100%; } /* sideNavi ------------------------- */ .viewer .btnPrev, .viewer .btnNext { margin-top: -25px; top: 50%; width: 50px; height: 50px; position: absolute; z-index: 101; } .viewer .btnPrev { left: 10px; background: #ccc url(../img/btnPrev.jpg) no-repeat center center; } .viewer .btnNext { right: 10px; background: #ccc url(../img/btnNext.jpg) no-repeat center center; } /* ======================================= ClearFixElements ======================================= */ .viewer ul:after { content: "."; height: 0; clear: both; display: block; visibility: hidden; } .viewer ul { display: inline-block; overflow: hidden; }
スライドショー部分の幅や高さはスクリプト側から制御するので、CSS側では幅100%だけ入れておきます。
ブラウザ幅の判別などもスクリプト側で制御するので、CSSでのメディアクエリー指定も特に使用しておりません。
(実際にページに組み込む際にはページのレイアウト制御等々で使用することになると思いますが)
オプションとしてスライドショーの左右にNEXT/BACKボタンを付けられるようにしてあるので、ボタンの色など見た目はCSSで指定します。
そして実際の動作スクリプトは以下の様になります。
◆SCRIPT <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script> $(function(){ $(window).load(function(){ var setElm = $('.viewer'), setMaxWidth = 800, setMinWidth = 320, fadeSpeed = 1500, switchDelay = 5000, sideNavi = 'off', // 'on' or 'off' sideHide = 'hide', // 'hide' or 'show' naviOpc = 0.5; setElm.each(function(){ var targetObj = $(this), findUl = targetObj.find('ul'), findLi = targetObj.find('li'), findLiFirst = targetObj.find('li:first'); findLi.css({display:'block',opacity:'0',zIndex:'99'}); findLiFirst.css({zIndex:'100'}).stop().animate({opacity:'1'},fadeSpeed); function timer(){ setTimer = setInterval(function(){ slideNext(); },switchDelay); } timer(); function slideNext(){ findUl.find('li:first-child').not(':animated').animate({opacity:'0'},fadeSpeed).next('li').css({zIndex:'100'}).animate({opacity:'1'},fadeSpeed).end().appendTo(findUl).css({zIndex:'99'}); } function slidePrev(){ findUl.find('li:first-child').not(':animated').css({zIndex:'99'}).animate({opacity:'0'},fadeSpeed).siblings('li:last-child').css({zIndex:'100'}).animate({opacity:'1'},fadeSpeed).prependTo(findUl); } targetObj.css({width:setMaxWidth,display:'block'}); // メイン画像をベースにエリアの幅と高さを設定 var setLiImg = findLi.find('img'), baseWidth = setLiImg.width(), baseHeight = setLiImg.height(); // レスポンシブ動作メイン function imgSize(){ var windowWidth = parseInt($(window).width()); if(windowWidth >= setMaxWidth) { targetObj.css({width:setMaxWidth,height:baseHeight}); findUl.css({width:baseWidth,height:baseHeight}); findLi.css({width:baseWidth,height:baseHeight}); } else if(windowWidth < setMaxWidth) { if(windowWidth >= setMinWidth) { targetObj.css({width:'100%'}); findUl.css({width:'100%'}); findLi.css({width:'100%'}); } else if(windowWidth < setMinWidth) { targetObj.css({width:setMinWidth}); findUl.css({width:setMinWidth}); findLi.css({width:setMinWidth}); } var reHeight = setLiImg.height(); targetObj.css({height:reHeight}); findUl.css({height:reHeight}); findLi.css({height:reHeight}); } } $(window).resize(function(){imgSize();}).resize(); // サイドナビボタン(有り無し) var agent = navigator.userAgent; if(sideNavi == 'on'){ targetObj.append('<a href="javascript:void(0);" class="btnPrev"></a><a href="javascript:void(0);" class="btnNext"></a>'); var btnPrev = targetObj.find('.btnPrev'),btnNext = targetObj.find('.btnNext'),btnPrevNext = targetObj.find('.btnPrev,.btnNext'); if(agent.search(/iPhone/) != -1 || agent.search(/iPad/) != -1 || agent.search(/iPod/) != -1 || agent.search(/Android/) != -1){ btnPrevNext.css({opacity:naviOpc}); } else { btnPrevNext.css({opacity:naviOpc}).hover(function(){ $(this).stop().animate({opacity:naviOpc+0.2},200); },function(){ $(this).stop().animate({opacity:naviOpc},200); }); } if(sideHide == 'hide'){ if(agent.search(/iPhone/) != -1 || agent.search(/iPad/) != -1 || agent.search(/iPod/) != -1 || agent.search(/Android/) != -1){ btnPrevNext.css({visibility:'visible'}); } else { btnPrevNext.css({visibility:'hidden'}); targetObj.hover(function(){ btnPrevNext.css({visibility:'visible'}); },function(){ btnPrevNext.css({visibility:'hidden'}); }); } } btnPrev.click(function(){switchPrev();}); btnNext.click(function(){switchNext();}); } // ボタン移動動作 function switchNext(){ findLi.not(':animated').parents('ul').each(function(){ clearInterval(setTimer); slideNext(); timer(); }); } function switchPrev(){ findLi.not(':animated').parents('ul').each(function(){ clearInterval(setTimer); slidePrev(); timer(); }); } }); }); }); </script>
スクリプト開始部分にある設定値の内容は以下の様になっています。
var setElm = $(‘.viewer’) | スライドショー全体を囲うブロック要素名(IDでも可) |
---|---|
setMaxWidth = 800 | スライドショー部分の最大幅 |
setMinWidth = 320 | スライドショー部分の最小幅 |
fadeSpeed = 1500 | フェードアニメーションスピード |
switchDelay = 5000 | スライドアニメーション待機時間 |
sideNavi = ‘off’ | 左右NEXT/BACKの表示/非表示(表示する場合は「on」) |
sideHide = ‘hide’ | 左右NEXT/BACKのロールオーバーで表示切り替えON/OFF(常に表示させる場合は「show」等) |
naviOpc = 0.5 | 左右NEXT/BACKの透過度 |
これらの設定値を変更することでもろもろ調整が可能になっています。
スクリプト全体はあまりシンプルと言える構成ではありませんが、少しの設定値を調整するだけで簡単に設置することは可能になっているかと思います。
画像サイズ(比率)によって各エリアの幅と高さを取得して制御していることもあり、使用する(切り替える)画像は全て幅と高さを同サイズのものを使用する必要があります。
オプション機能としてスライドショーの左右にNEXT/BACKのボタンを表示させるようにもしてあり、「sideNavi」を「’on’」や「’off’」とすることで表示/非表示を切り替えることができます。
(記述は「off」でなくても「on」じゃなければ何でもいいです・・・)
表示したNEXT/BACKボタンをスライドショーエリアにカーソルが乗った時のみ表示させるようにするには「sideHide」を「’hide’」とします。
常にボタンを表示させるにはここの値は「’show’」とします。
(記述は「show」でなくても「hide」じゃなければ何でもいいです・・・)
スライドショー自体は1ページ内に複数設置することも可能になっていますが、複数設置した際にNEXT/BACKボタンをつけるとどうも動作がうまくいかなくなるようなので、複数設置する場合はNEXT/BACKボタンは「off」にしてください。
※不完全ですみません。。
左右のボタン表示「on」マウスオーバーでボタン表示「hide」パターンのサンプルを別枠で表示
iPhoneやAndroid端末でも動作するハズ。
レスポンシブ対応のサムネイル付きクロスフェードスライドショーを実装する際にぜひ。。。