jQueryを使ってのコンテンツスライダーや画像スライドショーなどをできるだけシンプルなスクリプトでに実装する実験やサンプルをいくつか紹介してきていますが、最近よく見かける(流行り?)ブラウザウィンドウ画面の幅をめいっぱい使って、コンテンツ要素をスライドさせて魅せるコンテンツスライダーをまだ試したことがなかったので実験的に作ってみたのものを紹介してみます。
【2014/01/15】 フリック動作の追加及び、スライダー全体がレスポンシブ対応のタイプの改訂版スクリプトについてはこちらの記事から
jQueryでブラウザウィンドウ幅めいっぱいに要素を並べたコンテンツスライダーを設置する実験
今回のスライダーはなかなか言葉では説明しずらいのでまず動作サンプルから。
「jQueryでブラウザウィンドウ幅めいっぱいに要素を並べたコンテンツスライダーを設置する実験」サンプルを別枠で表示
スライダー中心にメイン表示エリアを設置して、その前後の画像は左右に透過させたような形でスライド要素をブラウザ枠めいっぱいに並べて配置しています。
(ウィンドウサイズを変更した際にも枠に合わせて左右の透過エリアが広がります)
左右の透過エリアはスライダーのNEXT/BACKボタンとなっているので、クリックすることで一つずつスライダーを移動させることができます。
NEXT/BACKボタンに加えて、表示するコンテンツ要素分のページネーションが付加するようにしてあるので、ページネーションの各ボタンをクリックさせることで任意のスライド番号へ移動させることも可能です。
動作仕様については以上になります。
全体構成についてまずはHTMLから。
◆HTML <div class="wideslider"> <ul> <li><a href="#1"><img src="img/photo01.jpg" width="800" height="500" alt="" /></a></li> <li><a href="#2"><img src="img/photo02.jpg" width="800" height="500" alt="" /></a></li> <li><a href="#3"><img src="img/photo03.jpg" width="800" height="500" alt="" /></a></li> <li><a href="#4"><img src="img/photo04.jpg" width="800" height="500" alt="" /></a></li> <li><a href="#5"><img src="img/photo05.jpg" width="800" height="500" alt="" /></a></li> </ul> </div><!--/.wideslider-->
クラスやIDを付けた任意のブロック要素の中に<ul>リストを使ってコンテンツ要素(サンプル画面で言うメイン画像)を並べます。
サンプルではコンテンツ要素を5つにしていますが、これを増減させるには単純に<li>の数を増減するだけです。
ページネーションや左右のNEXT/BACKボタンはスクリプト側から生成するようにしているのでHTMLには記述しません。
そしてCSSは以下の様になります。
◆CSS .wideslider { width: 100%; height: 500px; text-align: left; position: relative; overflow: hidden; } .wideslider ul, .wideslider ul li { float: left; display: inline; overflow: hidden; } .wideslider_base { top: 0; position: absolute; } .wideslider_wrap { top: 0; position: absolute; overflow: hidden; } .slider_prev, .slider_next { top: 0; overflow: hidden; position: absolute; z-index: 100; cursor: pointer; } .slider_prev {background: #fff url(../img/prev.jpg) no-repeat right center;} .slider_next {background: #fff url(../img/next.jpg) no-repeat left center;} .pagination { bottom: 10px; left: 0; width: 100%; height: 15px; text-align: center; position: absolute; z-index: 200; } .pagination a { margin: 0 5px; width: 15px; height: 15px; display: inline-block; overflow: hidden; background: #333; } .pagination a.active { filter:alpha(opacity=100)!important; -moz-opacity: 1!important; opacity: 1!important; } /* ======================================= ClearFixElements ======================================= */ .wideslider ul:after { content: "."; height: 0; clear: both; display: block; visibility: hidden; } .wideslider ul { display: inline-block; overflow: hidden; }
スライド左右の透過NEXT/BACKボタン部分の色・見た目やページネーションの色味などはCSSで指定します。
スライド要素の幅や高さについてはスクリプト側で制御するので、ここでは記述していません。
そして実際の動作スクリプトは以下の様になります。
◆SCRIPT <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script> <script type="text/javascript"> $(function(){ var $setElm = $('.wideslider'), baseWidth = 800, baseHeight = 500, slideSpeed = 500, delayTime = 5000, easing = 'linear', autoPlay = '1', // notAutoPlay = '0' btnOpacity = 0.5, pnOpacity = 0.5; $setElm.each(function(){ var targetObj = $(this); var widesliderWidth = baseWidth; var widesliderHeight = baseHeight; var wsSetTimer; targetObj.children('ul').wrapAll('<div class="wideslider_base"><div class="wideslider_wrap"></div><div class="slider_prev"></div><div class="slider_next"></div></div>'); var findBase = targetObj.find('.wideslider_base'); var findWrap = targetObj.find('.wideslider_wrap'); var findPrev = targetObj.find('.slider_prev'); var findNext = targetObj.find('.slider_next'); var baseListWidth = baseWidth; var baseListCount = findWrap.children('ul').children('li').length; var baseWrapWidth = (baseListWidth)*(baseListCount); var pagination = $('<div class="pagination"></div>'); targetObj.append(pagination); var baseList = findWrap.children('ul').children('li'); baseList.each(function(i){ $(this).css({width:(baseWidth),height:(baseHeight)}); pagination.append('<a href="javascript:void(0);" class="pn'+(i+1)+'"></a>'); }); var pnPoint = pagination.children('a'); var pnFirst = pagination.children('a:first'); var pnLast = pagination.children('a:last'); var pnCount = pagination.children('a').length; pnPoint.css({opacity:(pnOpacity)}).hover(function(){ $(this).stop().animate({opacity:'1'},300); }, function(){ $(this).stop().animate({opacity:(pnOpacity)},300); }); pnFirst.addClass('active'); pnPoint.click(function(){ if(autoPlay == '1'){clearInterval(wsSetTimer);} var setNum = pnPoint.index(this); var moveLeft = ((baseListWidth)*(setNum))+baseWrapWidth; findWrap.stop().animate({left: -(moveLeft)},slideSpeed,easing); pnPoint.removeClass('active'); $(this).addClass('active'); if(autoPlay == '1'){wsTimer();} }); var makeClone = findWrap.children('ul'); makeClone.clone().prependTo(findWrap); makeClone.clone().appendTo(findWrap); var allListWidth = findWrap.children('ul').children('li').width(); var allListCount = findWrap.children('ul').children('li').length; var allLWrapWidth = (allListWidth)*(allListCount); var windowWidth = $(window).width(); var posAdjust = ((windowWidth)-(baseWidth))/2; findBase.css({left:(posAdjust),width:(baseWidth),height:(baseHeight)}); findPrev.css({left:-(baseWrapWidth),width:(baseWrapWidth),height:(baseHeight),opacity:(btnOpacity)}); findNext.css({right:-(baseWrapWidth),width:(baseWrapWidth),height:(baseHeight),opacity:(btnOpacity)}); $(window).bind('resize',function(){ var windowWidth = $(window).width(); var posAdjust = ((windowWidth)-(baseWidth))/2; findBase.css({left:(posAdjust)}); findPrev.css({left:-(posAdjust),width:(posAdjust)}); findNext.css({right:-(posAdjust),width:(posAdjust)}); }).resize(); findWrap.css({left:-(baseWrapWidth),width:(allLWrapWidth),height:(baseHeight)}); findWrap.children('ul').css({width:(baseWrapWidth),height:(baseHeight)}); var posResetNext = -(baseWrapWidth)*2; var posResetPrev = -(baseWrapWidth)+(baseWidth); if(autoPlay == '1'){wsTimer();} function wsTimer(){ wsSetTimer = setInterval(function(){ findNext.click(); },delayTime); } findNext.click(function(){ findWrap.not(':animated').each(function(){ if(autoPlay == '1'){clearInterval(wsSetTimer);} var posLeft = parseInt($(findWrap).css('left')); var moveLeft = ((posLeft)-(baseWidth)); findWrap.stop().animate({left:(moveLeft)},slideSpeed,easing,function(){ var adjustLeft = parseInt($(findWrap).css('left')); if(adjustLeft == posResetNext){ findWrap.css({left: -(baseWrapWidth)}); } }); var pnPointActive = pagination.children('a.active'); pnPointActive.each(function(){ var pnIndex = pnPoint.index(this); var listCount = pnIndex+1; if(pnCount == listCount){ pnPointActive.removeClass('active'); pnFirst.addClass('active'); } else { pnPointActive.removeClass('active').next().addClass('active'); } }); if(autoPlay == '1'){wsTimer();} }); }).hover(function(){ $(this).stop().animate({opacity:((btnOpacity)+0.1)},100); }, function(){ $(this).stop().animate({opacity:(btnOpacity)},100); }); findPrev.click(function(){ findWrap.not(':animated').each(function(){ if(autoPlay == '1'){clearInterval(wsSetTimer);} var posLeft = parseInt($(findWrap).css('left')); var moveLeft = ((posLeft)+(baseWidth)); findWrap.stop().animate({left:(moveLeft)},slideSpeed,easing,function(){ var adjustLeft = parseInt($(findWrap).css('left')); var adjustLeftPrev = (posResetNext)+(baseWidth); if(adjustLeft == posResetPrev){ findWrap.css({left: (adjustLeftPrev)}); } }); var pnPointActive = pagination.children('a.active'); pnPointActive.each(function(){ var pnIndex = pnPoint.index(this); var listCount = pnIndex+1; if(1 == listCount){ pnPointActive.removeClass('active'); pnLast.addClass('active'); } else { pnPointActive.removeClass('active').prev().addClass('active'); } }); if(autoPlay == '1'){wsTimer();} }); }).hover(function(){ $(this).stop().animate({opacity:((btnOpacity)+0.1)},100); }, function(){ $(this).stop().animate({opacity:(btnOpacity)},100); }); }); }); </script>
スクリプト開始部分にある設定値の内容は以下の様になっています。
$setElm = $(‘.wideslider’) | 対象にするブロック要素名(IDでも可) |
---|---|
baseWidth = 800 | スライドさせるコンテンツ要素の幅 |
baseHeight = 500 | スライドさせるコンテンツ要素の高さ |
slideSpeed = 500 | スライドアニメーションスピード |
delayTime = 5000 | スライドアニメーション待機時間 |
easing = ‘linear’ | スライドアニメーションイージング |
autoPlay = ‘1’ | 自動スライドON/OFF(ON = 1 , OFF = 0) |
btnOpacity = 0.5 | 左右のNEXT/BACKエリアの透過具合 |
pnOpacity = 0.5 | ページネーションの透過具合 |
これらの設定値を変更することでもろもろ調整が可能になっています。
スクリプト全体はあまりシンプルと言える構成ではありませんが、少しの設定値を調整するだけで簡単に設置することは可能になっているかと思います。
設置の際の簡単な注意点としては、HTML構成上このコンテンツスライダー要素全体を囲うブロック要素があった場合は、
その要素の幅は100%になっている必要があります。併せて、この形状のコンテンツスライダーを1ページ内に複数設置することはあまりないかと思いますが、複数設置した際には自動スライド機能は一つ目のスライダーのみにしか動作しません。
※2016/01/09 改定
カスタマイズに関しては、jQueryイージングプラグインを使って簡単にスライドアニメーション動作に抑揚をつけたり、CSSを少し調整することでページネーションをスライダーエリアから外へ出すことなども可能です。
ページネーションについては、生成される際に個別に「.pn(n)」のクラスが付与されるようになっているので、CSS側からそれらのクラスに対して背景画像を指定することでサムネイル画像として表示させることも可能です。
※スライド要素が5つの場合はページネーションのクラスは「.pn1」 ~ 「.pn5」という風に個別に付与されます。
jQueryイージングプラグインを使ってスライドアニメーションにイージング処理をつけて、ページネーションをスライドエリアの外にしてサムネイル表示にした場合は以下の様な見た目にすることができます。
jQueryイージング+ページネーションをエリア外+サムネイル表示にしたパターンのサンプルを別枠で表示
ブラウザの幅をめいっぱい使ってスライダーを設置することで、ダイナミックな演出を組み込むことが可能かと思っています。
ブラウザウィンドウ幅めいっぱいのコンテンツスライダーを実装する際にぜひ。。。
サンプルファイルをダウンロードしたい方はこちらから
【2014/01/15】 フリック動作の追加及び、スライダー全体がレスポンシブ対応のタイプの改訂版スクリプトについてはこちらの記事から