jQueryでスライダー(横にジリジリと動いて永続するやつ)を作ってみた
個人引受分の仕事の関係で、横方向へジリジリと動くスライダーをjQueryで作る必要があり、久し振りに結構まともにjQueryを触ることになった。
なんで、いつものごとく雑記とコード(一応、プラグイン化した)を掲載。
いや、最初はまぁ同じ様なことしてるサイトっていっぱいあるし、コピペ用のコードなんかありふれているんだろうなぁと思っていたんだけどね。
ただ、レスポンシブのカラム設定だとか、ページをスクロールしていった際にスライドを開始させるタイミングの設定ができるものっていうのが中々どうして見当たらない。
探し始めて30分で、もうこりゃ自分で作ったほうが早いやと思って、やってみたのが経緯。
で、今回のコードはこれ。
「jquery.activescroll.js」で保存
プラグイン化してます。コピペが面倒な人のため、記事の最後の方にダウンロード先あり。一応。
/* * jQuery Active Roll by CattleMute * copyright (c) cattlemute * * Will follow the license of jQuery. */ (function($){ $.fn.activeroll = function(options){ var option = { frame: 30, position: 50, hover: true, hold: true, column: { normal: [0, 4], }, }; var static = { content: 'activeroll-content', wrap: 'activeroll-wrap', rebirth: 'activeroll-rebirth', column: 'activeroll-column', start: 'activeroll-start', active: 'activeroll-active', }; var config = $.extend(option, options); var inc = $(this), mv = new Array(), si; var ua = window.navigator.userAgent.toLowerCase(); var activeroll = (function(){ return{ init: function(){ inc.addClass(static.content) .css({'overflow': 'hidden', 'position': 'relative'}) .children().addClass(static.column); $('.' + static.content).wrapInner('<div class="' + static.rebirth + '" />') .each(function(){ var html = $(this).html(); $(this).append(html); $(this).children('.' + static.rebirth).css({'float': 'left'}); }); $('.' + static.content).wrapInner('<div class="' + static.wrap + '" />') .children('.' + static.wrap).css({'position': 'absolute', 'top': 0, 'left': 0}); $('.' + static.content).each(function(){ activeroll.disequip($(this)); }); this.stack(); this.size(); this.clip(); }, clip: function(){ $(window).bind({ 'load': function(){ activeroll.showin(); activeroll.interval(); }, 'resize': function(){ $('.' + static.content).each(function(){ activeroll.disequip($(this)); }); activeroll.size(); }, 'scroll': function(){ activeroll.showin(); }, }); $('.' + static.content).bind({ 'mouseenter': function(){ if(config.hover && (ua.indexOf('windows') > -1 || ua.indexOf('macintosh') > -1 || ua.indexOf('linux') > -1)) $(this).addClass(static.active); }, 'mouseleave': function(){ $(this).removeClass(static.active); }, }); if('ontouchstart' in window){ $('.' + static.content).bind({ 'touchstart': function(){ if(config.hold) $('.' + static.content).addClass(static.active); }, 'touchend': function(){ $('.' + static.content).removeClass(static.active); }, }); } }, stack: function(){ $('.' + static.content).each(function(n){ mv[n] = $(this); }); }, lack: function(base){ if(base.find('.' + static.rebirth).eq(0).find('.' + static.column).length <= activeroll.colset()) return true; else return false; }, disequip: function(base){ if(this.lack(base)){ base.children('.' + static.wrap).css({'left': 0}); base.find('.' + static.rebirth).eq(1).css({'display': 'none'}); }else{ base.find('.' + static.rebirth).eq(1).css({'display': ''}); } }, size: function(){ $('.' + static.content).each(function(){ var w = $(this).width() / activeroll.colset(); $(this).find('.' + static.column).css({'width': w, 'float': 'left'}); $(this).find('.' + static.rebirth).css({'width': w * $(this).find('.' + static.column).length / 2}); $(this).css({'height': $(this).find('.' + static.rebirth).outerHeight()}) .children('.' + static.wrap).css({'width': w * $(this).find('.' + static.column).length}); }); }, colset: function(){ var w = window.innerWidth, r = 1; for(var key in config.column){ if(config.column[key][0] >= w || config.column[key][0] == 0){ r = config.column[key][1]; } } return r; }, showin: function(){ $('.' + static.content).each(function(){ if( $(this).offset().top <= $(window).scrollTop() + (window.innerHeight * (config.position * 0.01)) ){ $(this).addClass(static.start); } }); }, interval: function(){ si = setInterval(function(){ for(var i = 0; i < mv.length; i++){ var m = mv[i], p = parseInt(m.children('.' + static.wrap).css('left'), 10); if(m.hasClass(static.start) && ! m.hasClass(static.active) && ! activeroll.lack(m)){ if(m.find('.' + static.rebirth).width() >= p * -1 ) m.children('.' + static.wrap).css({'left': p - 1 }); else m.children('.' + static.wrap).css({'left': 0 }); } } }, 1000 / config.frame ); }, }; })(); activeroll.init(); return(this); }; })(jQuery);
スクリプトの起動コード
(function($){ $(document).ready(function(){ $('.activeroll').activeroll({ frame: 30, position: 50, hover: true, hold: true, column:{ normal: [0, 4], tablet: [1024, 2], mobile: [667, 2], } }); }); })(jQuery);
プラグインのプロパティは以下のようになっています。
- frame…スライドの速度。数値が大きいほど速くなります。
- position…ページをスクロールしてスライダーを通過したときに、どのタイミングでスライダーを動かし始めるか。
0で画面上端、50で画面半分、100で画面下端。 - hover…デスクトップ端末のみ。
スライダーが動いている領域にマウスを置いたときにスライドを停止するかどうか。
trueは停止するようにして、falseは停止しないようにします。 - hold…タッチ端末のみ。
スライダーが動いている領域にタッチした際にスライドを停止するかどうか。
trueは停止するようにして、falseは停止しないようにします。 - column…レスポンシブ時のカラム数。
様式は、column: { お好きな名称: [ ウィンドウサイズ, カラムの数 ], ………. }
tabletとかmobileとか書いているけど、様式さえ守ればいくらでも増やせます。(normalだけ固定)
…我ながら若干わかりにくいプロパティを付けたなぁと思う。
HTML
親 > 子で作ればOK。(以下の例ならactiveroll > column。naiyouのところはただのラッパー。)
<div class="activeroll"> <div class="column"> <div class="naiyou"> <h2>ボックス</h2> <p>ボックスのテキストです。</p> </div> </div> <div class="column"> <div class="naiyou"> <h2>ボックス</h2> <p>ボックスのテキストです。</p> </div> </div> <div class="column"> <div class="naiyou"> <h2>ボックス</h2> <p>ボックスのテキストです。</p> </div> </div> <div class="column"> <div class="naiyou"> <h2>ボックス</h2> <p>ボックスのテキストです。</p> </div> </div> <div class="column"> <div class="naiyou"> <h2>ボックス</h2> <p>ボックスのテキストです。</p> </div> </div> <div class="column"> <div class="naiyou"> <h2>ボックス</h2> <p>ボックスのテキストです。</p> </div> </div> </div>
動作サンプル
jquery.activeroll.jsのサンプル
動作はこんな感じで動きます。
このスライドはサンプルなので文字だけですが、画像だけとか画像とテキストが混在しても入れられる…はず。
複数設置も考慮
一応、そのように作っているのでできるかと思う。
ページ読み込みから
いきなりぐるぐる回りだすのもアレなので、スクロールでスライダーを通過した際に発火するようにしてます。
カラムやデバイスサイズ
オブジェクトと配列を利用してやります。
(一応、上にも書いておきましたが…。)
ちなみに
HTMLで設定した要素が、デバイスサイズで設定しているカラム数以下のときはスライドはしない仕様。
だけど
画面幅を縮めたりしてHTMLで設定した要素>デバイスサイズで設定しているカラム数となったときに動くようになってます。
動作サンプルはこんなところです。
ご利用はご自由にどうぞ。
こんなコードでもよければよろしければどうぞ。
上記のファイルは、こちらからダウンロードできます。
※3/12 ちょっとだけコード修正。