少し前に「jQueryでページの最上部に位置固定した、フルスクリーンスライドショー(クロスフェード)を設置する方法」と題して、ページ最上部に位置固定したクロスフェードスライドショーのサンプルを紹介しましたが、同様の形でクロスフェードではなくフルスクリーンの状態で画像全体が横スライドして見せるスクリプトサンプルを作ってみたので紹介してみます。
jQueryでページの最上部に位置固定したフルスクリーンスライダーを設置する方法
言葉では少々説明しずらいのでまず動作サンプルから。
「jQueryでページの最上部に位置固定したフルスクリーンスライダーを設置する方法」サンプルを別枠で表示
ページ最上部に位置固定したフルスクリーンサイズでのスライドショーを設置します。
※画像全体は横スライドして切り替え
ページをスクロールさせるとフルスクリーンスライドショーはページ上部に固定されたままになり、下からコンテンツ要素が出現してきます。
スライドショー全体はブラウザサイズを変化させてもウィンドウの幅と高さに合わせて伸縮する構成になっており、スクロール位置がページ最上部にある場合に画面めいっぱいで収まる形になっています。
このフルスクリーンスライドショーの全体構成について、まずはHTMLから。
◆HTML <div id="container"> <div class="fullSlider"> <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><!-- /.fullSlider --> <div class="wrapper"> <h1>jQuery HeaderFixed FullScreen Slider</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=”fullSlider”>で囲われた部分のみとなり、その他の部分はサンプル画面を生成するサンプル要素になります。
サンプルでは5枚の画像を<li>を5つ並べて切り替えています。
表示個数を増減するには<li>を増やしたり減らしたりするだけになっています。
※<li>が一つだけの場合はスライド機能は動作せず静止画像一枚がフルスクリーン表示します。
これに対してCSSは以下の様になっています。
◆CSS #container { width: 100%; text-align: center; } /* fullSlider --------------------------- */ .fullSlider { width: 100%; text-align: left; position: relative; overflow: hidden; } .fullSlider ul, .fullSlider ul li { float: left; display: inline; overflow: hidden; } .fullSlider ul li { position: relative; } .fullSlider ul li img { top: 50%; left: 50%; position: absolute; } .fullViewWrap { top: 0; position: fixed; /* absolute or fixed */ overflow: hidden; } /* SideNavi ------------------------- */ .fullSlider .btnPrev, .fullSlider .btnNext { margin-top: -25px; top: 50%; width: 50px; height: 50px; position: fixed; /* absolute or fixed */ z-index: 105; } .fullSlider .btnPrev { left: 10px; background: transparent url(../img/btnPrev.png) no-repeat center center; } .fullSlider .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 ======================================= */ .fullSlider ul:after { content: "."; height: 0; clear: both; display: block; visibility: hidden; } .fullSlider 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 = $('.fullSlider'); slideSpeed = 500; switchDelay = 5000; easing = 'linear'; sideNavi = 'on'; // 'on' or 'off' sideHide = 'hide'; // 'hide' or 'show' autoPlay = '1'; // notAutoPlay = '0' naviOpc = 0.5; pnOpacity = 0.5; ua = navigator.userAgent; $(window).load(function(){ setElm.each(function(){ targetObj = $(this); targetObj.children('ul').wrapAll('<div class="fullViewWrap"></div>'); var findWrap = targetObj.find('.fullViewWrap'); var baseList = findWrap.find('li'), baseListLink = findWrap.find('li').children('a'), baseListCount = findWrap.find('li').length; baseList.each(function(i){ $(this).attr('class','viewList' + (i + 1).toString()); }); if(baseListCount > 1){ // ページネーションSET var pagination = $('<div class="pagiNation"></div>'); targetObj.append(pagination); baseList.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; 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); }); } pnFirst.addClass('pnActive'); pnPoint.click(function(){ if(autoPlay == '1'){clearInterval(setAutoTimer);} var setNum = pnPoint.index(this), moveLeft = ((wdWidth)*(setNum))+baseWrapWidth; findWrap.stop().animate({left: -(moveLeft)},slideSpeed,easing); pnPoint.removeClass('pnActive'); $(this).addClass('pnActive'); activePos(); if(autoPlay == '1'){slideTimer();} }); function activePos(){ var posActive = pagination.find('.pnActive'); posActive.each(function(){ var posIndex = pnPoint.index(this), setMainList = findWrap.find('.mainList').children('li'); setMainList.removeClass('mainActive').eq(posIndex).addClass('mainActive'); }); } function pnActiveMoveNext(){ var pnPointActive = pagination.children('.pnActive'); pnPointActive.each(function(){ var pnIndex = pnPoint.index(this), listCount = pnIndex+1; if(pnCount == listCount){ pnPointActive.removeClass('pnActive'); pnFirst.addClass('pnActive'); } else { pnPointActive.removeClass('pnActive').next().addClass('pnActive'); } }); } function pnActiveMovePrev(){ var pnPointActive = pagination.children('.pnActive'); pnPointActive.each(function(){ var pnIndex = pnPoint.index(this), listCount = pnIndex+1; if(1 == listCount){ pnPointActive.removeClass('pnActive'); pnLast.addClass('pnActive'); } else { pnPointActive.removeClass('pnActive').prev().addClass('pnActive'); } }); } // ボタン移動動作 function switchNext(){ findWrap.not(':animated').each(function(){ if(autoPlay == '1'){clearInterval(setAutoTimer);} var posLeft = parseInt($(findWrap).css('left')), moveLeft = ((posLeft)-(wdWidth)); findWrap.stop().animate({left:(moveLeft)},slideSpeed,easing,function(){ var adjustLeft = parseInt($(findWrap).css('left')); if(adjustLeft <= posResetNext){ findWrap.css({left: -(baseWrapWidth)}); } }); pnActiveMoveNext(); activePos(); if(autoPlay == '1'){slideTimer();} }); } function switchPrev(){ findWrap.not(':animated').each(function(){ if(autoPlay == '1'){clearInterval(setAutoTimer);} var posLeft = parseInt($(findWrap).css('left')), moveLeft = ((posLeft)+(wdWidth)); findWrap.stop().animate({left:(moveLeft)},slideSpeed,easing,function(){ var adjustLeft = parseInt($(findWrap).css('left')), adjustLeftPrev = (posResetNext)+(wdWidth); if(adjustLeft >= posResetPrev){ findWrap.css({left: adjustLeftPrev}); } }); pnActiveMovePrev(); activePos(); if(autoPlay == '1'){slideTimer();} }); } function slideTimer(){ setAutoTimer = setInterval(function(){ switchNext(); },switchDelay); } if(autoPlay == '1'){slideTimer();} // サイドナビボタン(有り無し) 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 stretchImg = findWrap.find('img'), imgWidth = stretchImg.width(), imgHeight = stretchImg.height(), selfWH = imgWidth / imgHeight; // フルスクリーン(レスポンシブ)動作 function setSlide(){ wdWidth = $(window).width(); wdHeight = $(window).height(); findLi = findWrap.find('li'); setWrapLeft = parseInt(findWrap.css('left')); setlistWidth = findLi.width(); setLeft = setWrapLeft / setlistWidth; setElm.css({height:wdHeight}); findLi.css({width:wdWidth,height:wdHeight}); baseWrapWidth = wdWidth*baseListCount; ulCount = findWrap.find('ul').length; if(ulCount == 1){ var makeClone = findWrap.children('ul'); makeClone.clone().prependTo(findWrap); makeClone.clone().appendTo(findWrap); findWrap.children('ul').eq('1').addClass('mainList'); var mainList = findWrap.find('.mainList').children('li'); mainList.eq('0').addClass('mainActive'); allListCount = findWrap.find('li').length; } allLWrapWidth = wdWidth*allListCount; posAdjust = ((wdWidth)-(wdWidth))/2; findWrap.css({width:allLWrapWidth,height:wdHeight}); findWrap.children('ul').css({width:baseWrapWidth,height:wdHeight}); var stretchImg = findLi.find('img'); posResetNext = -(baseWrapWidth)*2; posResetPrev = -(baseWrapWidth)+(wdWidth); adjLeft = wdWidth * setLeft; findWrap.css({left:adjLeft}); // 画像フルスクリーン調整 var strWidth = $(window).width(), strHeight = $(window).height(), calHeight = strWidth / selfWH; if(calHeight < $(window).height()){ calHeight = $(window).height(); strWidth = calHeight * selfWH; } stretchImg.css({marginTop:-calHeight/2,marginLeft:-strWidth/2,width:strWidth,height:calHeight}); } setSlide(); $(window).on('resize',function(){ if(autoPlay == '1'){clearInterval(setAutoTimer);} setSlide(); if(autoPlay == '1'){slideTimer();} }).resize(); findWrap.css({left:-(baseWrapWidth)}); } $('body').css({opacity:'0',visibility:'visible'}).stop().animate({opacity:'1'},1000); }); }); }); </script>
スクリプト開始部分にある各種設定値の内容については以下の様になっています。
setElm = $(‘.fullSlider’); | フルスクリーンスライダー全体を囲うブロック要素(IDでも可) |
---|---|
slideSpeed = 500; | スライドアニメーションスピード |
switchDelay = 5000; | スライドアニメーション待機時間 |
easing = ‘linear’; | スライドする際のイージング |
sideNavi = ‘on’; | 左右NEXT/BACKの表示/非表示(非表示の場合は「off」等) |
sideHide = ‘hide’; | 左右NEXT/BACKのロールオーバーで表示切り替えON/OFF(常に表示させる場合は「show」等) |
autoPlay = ‘1’; | 自動スライドON/OFF(ON = 1 , OFF = 0 |
naviOpc = 0.5; | 左右NEXT/BACKの透過度 |
pnOpacity = 0.5; | ページネーションボタンの透過度 |
これらの設定値を変更することで微調整が可能になっています。
スクリプト全体はあまりシンプルと言える構成ではありませんが、少しの設定値を調整するだけで簡単に設置することが可能になっているかと思います。
スライドショーの左右にあるNEXT/BACKボタンは「sideNavi」の値を「’on’」や「’off’」とすることで表示/非表示を切り替えることができます。
(記述は「off」でなくても「on」じゃなければ何でもいいです・・・)
表示したNEXT/BACKボタンをスライドショーエリアにカーソルが乗った時(ロールオーバー)のみ表示させるようにするには「sideHide」を「’hide’」とします。
常にボタンを表示させるにはここの値は「’show’」とします。
(記述は「show」でなくても「hide」じゃなければ何でもいいです・・・)
各スライドに画像以外要素を入れる場合は、フルスクリーンで表示させる画像に対して任意のクラスをつけてスクリプト178行目を「var stretchImg = findWrap.find(‘.fullImg’)」といったように「img」タグから任意のクラス名に変更させることで可能になるかと思います。
(CSS側のimg対象も要調整)
「jquery.easing.js」プラグインを併用することでスライドする際のアニメーションにさまざまなイージングを設定することも可能です。
上記で紹介したサンプルではスライドショー内に左右のボタンやページネーションをつけてありますが、それらを省いて画像がスライドするだけのシンプルな形でのスライドショーを実装する場合は次の様な形になります。
画像がスライドするだけのシンプルなスライドショーで実装する
「画像がスライドするだけのシンプルなスライドショーで実装する」サンプルを別枠で表示
こちらのパターンではページ最上部のフルスクリーンスライドショーには、左右のボタンやページネーションは実装しない構成で、画像がスライドするだけのシンプルなスライドショーになっています。
全体構成については、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側で
「.fullSlider ul」
「.fullSlider .btnPrev,.fullSlider .btnNext」
「.pagiNation」
上記の「position」の値を「absolute」に変更します。
◆CSS .fullSlider ul { top: 50%; left: 50%; width: 100%; position: absolute; /* absolute or fixed */ overflow: hidden; } .fullSlider .btnPrev, .fullSlider .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パターンにて、ページ最上部にフルスクリーンスライダーを実装する方法の紹介でした。
各サンプルでは画像だけをスライドさせるスライダーになっていますが、その上(前面)にロゴ画像やメニューボタンやテキストなどのパーツ類を重ねて配置させることも可能かと思います。
ページ最上部に位置固定したフルスクリーンスライダーを実装する際にぜひ。。。