最近のWebサイトでは写真をフルスクリーンでダイナミックに見せる技法や演出が多く見られます。
背景画像のフルスクリーン表示やフルスクリーンのスライドショーなど様々ありますが、jQueryを使って、ページ最上部(ページヘッダー)にフルスクリーンでのスライドショーを設置し、スクロールすると下から通常のコンテンツが表示される、というページ構成を実装するスクリプトを作ってみたので紹介してみます。
jQueryでページの最上部に位置固定したフルスクリーンスライドショー(クロスフェード)を設置する方法
少々言葉では説明しずらいのでまず動作サンプルから。
「jQueryでページ上部にフルスクリーンスライドショーを設置する方法」サンプルを別枠で表示
ページの最上部にフルスクリーンサイズにて画像がクロスフェードで切り替わるスライドショーを設置し、ページをスクロールさせるとページ上部にフルスクリーンスライドショーが固定されたまま下からコンテンツ要素が出現します。
スライドショー全体はブラウザサイズを変化させてもウィンドウの幅と高さに合わせて伸縮する構成になっており、スクロールがページ最上部にある場合に画面めいっぱいで収まる形になっています。
このフルスクリーンスライドショーの全体構成について、まずはHTMLから。
◆HTML <div id="container"> <div class="fullSlideShow"> <ul> <li><a href="#1"><img src="img/photo01.jpg" alt=""></a></li> <li><a href="#2"><img src="img/photo02.jpg" alt=""></a></li> <li><a href="#3"><img src="img/photo03.jpg" alt=""></a></li> <li><a href="#4"><img src="img/photo04.jpg" alt=""></a></li> <li><a href="#5"><img src="img/photo05.jpg" alt=""></a></li> </ul> </div><!-- /.fullSlideShow --> <div class="wrapper"> <h1>jQuery Responsive FullWide SlideShow</h1> <div class="contents"> <p>ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。ここからコンテンツエリア。これはダミーテキストです。</p> ・ ・ ・ </div><!-- /.contents --> <small>COPYRIGHT © <a href="https://black-flag.net/">BLACKFLAG.NET</a> ALL RIGHTS RESERVED.</small> </div><!-- /.wrapper --> </div><!-- /#container -->
フルスクリーンスライドショーを実装するHTML部分は<div class=”fullSlideShow”>で囲われた部分のみとなり、その他の部分はサンプル画面を生成するサンプル要素になります。
サンプルでは5枚の画像を<li>を5つ並べて切り替えています。
表示個数を増減するには<li>を増やしたり減らしたりするだけになっています。
<li>が一つだけの場合はスライドショー機能は動作せずに静止画像一枚がフルスクリーンで表示されます。
これに対してCSSは以下の様になっています。
◆CSS #container { width: 100%; text-align: center; } /* fullSlideShow --------------------------- */ .fullSlideShow { width: 100%; text-align: left; position: relative; overflow: hidden; } .fullSlideShow ul { top: 50%; left: 50%; width: 100%; position: fixed; /* absolute or fixed */ overflow: hidden; } .fullSlideShow ul li { top: 0; left: 0; width: 100%; display: none; position: absolute; } .fullSlideShow ul li img { width: 100%; } /* SideNavi ------------------------- */ .fullSlideShow .btnPrev, .fullSlideShow .btnNext { margin-top: -25px; top: 50%; width: 50px; height: 50px; position: fixed; /* absolute or fixed */ z-index: 105; } .fullSlideShow .btnPrev { left: 10px; background: transparent url(../img/btnPrev.png) no-repeat center center; } .fullSlideShow .btnNext { right: 10px; background: transparent url(../img/btnNext.png) no-repeat center center; } /* PagiNation --------------------------- */ .pagiNation { bottom: 30px; left: 0; width: 100%; height: 15px; text-align: center; position: fixed; /* absolute or fixed */ z-index: 110; /* 非表示にする場合は「90」以下に */ visibility: visible; /* 非表示にする場合は「hidden」に */ } .pagiNation a { margin: 0 5px; width: 20px; height: 20px; display: inline-block; overflow: hidden; background: #000; } .pagiNation a.pnActive { filter:alpha(opacity=100)!important; -moz-opacity: 1!important; opacity: 1!important; } /* Wrapper --------------------------- */ #wrapper { width: 100%; text-align: left; background: #fff; position: relative; z-index: 120; } .contents { padding: 30px 50px 50px 50px; } .contents p { padding-bottom: 3em; line-height: 180%; } /* ======================================= ClearFixElements ======================================= */ .fullSlideShow ul:after { content: "."; height: 0; clear: both; display: block; visibility: hidden; } .fullSlideShow ul { display: inline-block; overflow: hidden; }
スライドショー内の左右のNEXT/BACKボタン部分の見た目やページネーションの形状などはCSSで指定します。
スライド要素の幅や高さについては、スクリプト側で制御するので、ここでは記述していません。
スライドショーから後に続くコンテンツ要素(サンプルで言う「#wrapper」)に対しては「background: #fff;」「position: relative;」「z-index: 120;」は必須となっております。(背景色に関しては任意の色や画像で可)
そして実際の動作スクリプトは以下の様になります。
◆SCRIPT <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script> $(function(){ setElm = $('.fullSlideShow'); fadeSpeed = 1000; switchDelay = 5000; easing = 'linear'; sideNavi = 'on'; // 'on' or 'off' sideHide = 'hide'; // 'hide' or 'show' naviOpc = 0.5; pnOpacity = 0.5; ua = navigator.userAgent; $(window).load(function(){ setElm.each(function(){ var targetObj = $(this), findUl = targetObj.find('ul'), findLi = findUl.find('li'), findLiCount = findLi.length, findLiFirst = findUl.find('li:first'); findLi.each(function(i){ $(this).attr('class','viewList' + (i + 1).toString()); }); findLi.css({display:'block',opacity:'0',zIndex:'99'}); findLiFirst.addClass('mainActive').css({zIndex:'100'}).stop().animate({opacity:'1'},fadeSpeed); if(findLiCount > 1){ // ページネーションSET var pagination = $('<div class="pagiNation"></div>'); targetObj.append(pagination); findLi.each(function(i){ pagination.append('<a href="javascript:void(0);" class="pn'+(i+1)+'"></a>'); }); var pnPoint = pagination.children('a'), pnFirst = pagination.children('a:first'), pnLast = pagination.children('a:last'), pnCount = pagination.children('a').length; pnFirst.addClass('pnActive'); if(ua.search(/iPhone/) != -1 || ua.search(/iPad/) != -1 || ua.search(/iPod/) != -1 || ua.search(/Android/) != -1){ pnPoint.css({opacity:(pnOpacity)}); } else { pnPoint.css({opacity:(pnOpacity)}).hover(function(){ $(this).stop().animate({opacity:'1'},300); }, function(){ $(this).stop().animate({opacity:(pnOpacity)},300); }); } pnPoint.click(function(){ clearInterval(setAutoTimer); var setNum = pnPoint.index(this), showCont = setNum+1; findUl.find('.viewList' + (showCont)).siblings().removeClass('mainActive').stop().animate({opacity:'0'},fadeSpeed,function(){$(this).css({zIndex:'99'});}); findUl.find('.viewList' + (showCont)).addClass('mainActive').stop().animate({opacity:'1'},fadeSpeed,function(){$(this).css({zIndex:'100'});}); pnPoint.removeClass('pnActive'); $(this).addClass('pnActive'); fadeTimer(); }); // ボタン移動動作 function switchNext(){ var setActive = pagination.find('.pnActive'); setActive.each(function(){ var pnLengh = pnPoint.length, pnIndex = pnPoint.index(this), pnCount = pnIndex+1; if(pnLengh == pnCount){ pnFirst.click(); } else { $(this).next('a').click(); } }); } function switchPrev(){ var setActive = pagination.find('.pnActive'); setActive.each(function(){ var pnLengh = pnPoint.length, pnIndex = pnPoint.index(this), pnCount = pnIndex+1; if(1 == pnCount){ pnLast.click(); } else { $(this).prev('a').click(); } }); } function fadeTimer(){ setAutoTimer = setInterval(function(){ switchNext(); },switchDelay); } fadeTimer(); // サイドナビボタン(有り無し) 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(ua.search(/iPhone/) != -1 || ua.search(/iPad/) != -1 || ua.search(/iPod/) != -1 || ua.search(/Android/) != -1){ btnPrevNext.css({opacity:naviOpc}); } else { btnPrevNext.css({opacity:naviOpc}).hover(function(){ $(this).stop().animate({opacity:'1'},200); },function(){ $(this).stop().animate({opacity:naviOpc},200); }); } if(sideHide == 'hide'){ if(ua.search(/iPhone/) != -1 || ua.search(/iPad/) != -1 || ua.search(/iPod/) != -1 || ua.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();}); } } // メイン画像をベースにエリアの幅と高さを設定 var setLiImg = findLi.find('img'), baseWidth = setLiImg.width(), baseHeight = setLiImg.height(), selfWH = baseWidth / baseHeight; // フルスクリーン(レスポンシブ)動作メイン function setArea(){ var wdWidth = $(window).width(), wdHeight = $(window).height(), rwdHeight = wdWidth / selfWH; if(rwdHeight < $(window).height()){ rwdHeight = $(window).height(); wdWidth = rwdHeight * selfWH; } targetObj.css({height:wdHeight}); findUl.css({marginTop:-rwdHeight/2,marginLeft:-wdWidth/2,width:wdWidth,height:rwdHeight}); findLi.css({height:rwdHeight}); } $(window).resize(function(){setArea();}).resize(); $('body').css({visibility:'visible'}); }); }); }); </script>
スクリプト開始部分にある設定値の内容は以下の様になっています。
setElm = $(‘.fullSlideShow’); | フルスクリーンスライドショー全体を囲うブロック要素(IDでも可) |
---|---|
fadeSpeed = 1000; | フェードアニメーションスピード |
switchDelay = 5000; | スライドアニメーション待機時間 |
easing = ‘linear’; | スライドする際のイージング |
sideNavi = ‘on’; | 左右NEXT/BACKの表示/非表示(非表示の場合は「off」等) |
sideHide = ‘hide’; | 左右NEXT/BACKのロールオーバーで表示切り替えON/OFF(常に表示させる場合は「show」等) |
naviOpc = 0.5; | 左右NEXT/BACKの透過度 |
pnOpacity = 0.5; | ページネーションボタンの透過度 |
これらの設定値を変更することで微調整が可能になっています。
スクリプト全体はあまりシンプルと言える構成ではありませんが、少しの設定値を調整するだけで簡単に設置することが可能になっているかと思います。
スライドショーの左右にあるNEXT/BACKボタンは「sideNavi」の値を「’on’」や「’off’」とすることで表示/非表示を切り替えることができます。
(記述は「off」でなくても「on」じゃなければ何でもいいです・・・)
表示したNEXT/BACKボタンをスライドショーエリアにカーソルが乗った時(ロールオーバー)のみ表示させるようにするには「sideHide」を「’hide’」とします。
常にボタンを表示させるにはここの値は「’show’」とします。
(記述は「show」でなくても「hide」じゃなければ何でもいいです・・・)
上記で紹介したサンプルでは、スライドショー内に左右のボタンやページネーションをつけてありますが、それらを省いて画像がクロスフェードするだけのシンプルな形でのスライドショーを実装する場合は次の様な形になります。
画像がクロスフェードするだけのシンプルなスライドショーで実装する
「画像がクロスフェードするだけのシンプルなスライドショーで実装する」サンプルを別枠で表示
こちらのパターンではページ最上部のフルスクリーンスライドショーには左右のボタンやページネーションは実装しない構成で画像がクロスフェードするだけのシンプルなスライドショーになっています。
全体構成については、HTMLはそのまま、CSS側では「.pagiNation」の「z-index」と「visibility」の値を非表示にする設定に変更します。
◆CSS /* PagiNation --------------------------- */ .pagiNation { bottom: 30px; left: 0; width: 100%; height: 15px; text-align: center; position: fixed; /* absolute or fixed */ z-index: 90; /* 非表示にする場合は「90」以下に */ visibility: hidden; /* 非表示にする場合は「hidden」に */ }
スクリプト側では開始部分の設定値にて「sideNavi」を「’off’」にしておきます。
以上の変更で左右のボタンやページネーションをつけない形でのフルスクリーンスライドショーが実装可能になります。
最後に、ページ上部に配置するフルスクリーンスライドショーを位置固定せずにユーザーのスクロール動作に合わせて、上にスクロールしていくパターンのサンプルについて。
スライドショーをページ上部に固定させずに実装する
「スライドショーをページ上部に固定させずに実装する」サンプルを別枠で表示
このパターンではページ最上部に設置してあるフルスクリーンスライドショーはページをスクロールすることによって位置が固定されることなくコンテンツ要素と一緒に上へスクロールされるようになっています。
全体構成については、HTMLとスクリプトはそのままで、CSS側で
「.fullSlideShow ul」
「.fullSlideShow .btnPrev,.fullSlideShow .btnNext」
「.pagiNation」
上記の「position」の値を「absolute」に変更します。
◆CSS .fullSlideShow ul { top: 50%; left: 50%; width: 100%; position: absolute; /* absolute or fixed */ overflow: hidden; } .fullSlideShow .btnPrev, .fullSlideShow .btnNext { margin-top: -25px; top: 50%; width: 50px; height: 50px; position: absolute; /* absolute or fixed */ z-index: 105; } .pagiNation { bottom: 30px; left: 0; width: 100%; height: 15px; text-align: center; position: absolute; /* absolute or fixed */ z-index: 110; /* 非表示にする場合は「90」以下に */ visibility: visible; /* 非表示にする場合は「hidden」に */ }
以上の3パターンにてページ最上部にフルスクリーンスライドショーを実装する方法の紹介でした。
各サンプルではただ画像だけをクロスフェードで切り替えるだけのスライドショーになっていますが、その上(前面)にロゴ画像やメニューボタンなどを被せる形で入れ込むことで、最近「ヒーローヘッダー」と呼ばれるパーツとして実装することも可能かと思っています。
ページ最上部に固定したフルスクリーンスライドショーを実装する際にぜひ。。。