TechNote

とあるエンジニアのただのメモ

jQueryでスライダー機能を実装 - 横幅いっぱいのスライダーFullWideSlider

以前のエントリー jQueryでスライダー機能を実装 - jQuery slider2 で、jQueryスライダー設置の練習が済んだところで、少々本格的な「横幅いっぱい」のjQueryスライダーを設置してみたのでメモ。




1.横幅いっぱいのスライダーとは

昨今のWebサイトでよく見られる、横方向に画像を流すスライダーをのことをここでは「横幅いっぱいのスライダー」と呼ぶことにする。企業サイトなどでもよく見かける。

今回は、中央に位置するメインの画像以外、左右の画像は透過させたように表示させるようなものを探した。例えば下図のようなもの。

放っておくと設定秒数おきに画像が切り替わるが、nextボタンやbackボタンクリックでも左右の画像へ移動できる。ものによってはページネーションを表示させることが可能なものもある。


f:id:kojikoji75:20130720182345p:plain




2.jQuery FullWideSliderの設置方法

body内へ記述

body内のスライダーを表示させたい部分に下記のような要領で記述。以下は3つの画像を切り替える例だが、画像数を増やす場合はli要素を追記するだけ。

<div class="wideslider">
<ul>
<li><a href="#1"><img src="image/sample_001.jpg" width="980" height="340" alt="" /></a></li>
<li><a href="#2"><img src="image/sample_002.jpg" width="980" height="340" alt="" /></a></li>
<li><a href="#3"><img src="image/sample_003.jpg" width="980" height="340" alt="" /></a></li>
</ul>
</div>
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;
}

.wideslider ul:after {
	content: ".";
	height: 0;
	clear: both;
	display: block;
	visibility: hidden;
}

.wideslider ul {
	display: inline-block;
	overflow: hidden;
}
scriptの記述

head内に下記scriptを貼り付ける。またはjsファイルに分けて読み込む。

<script type="text/javascript" src="js/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;
		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 = findWrap.children('ul').children('li').width();
		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)});
		});

		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>
3.問題点

FullWideSliderは設置もとても簡単であり、細かいところまで設定可能で、個人的には理想の動きをしてくれる横幅いっぱいのスライダーであった。

しかし自分の環境では、FireFoxでは特に問題なく動作したものの、ieで使用した場合(ie9)スライド回数が増すごとに画像の位置がずれてきて、ある程度ずれが蓄積された段階で一切画像が表示されなくなるという不具合(?)があった。

コードを追って原因を追究するよりも、おそらく別のものを試したほうが早いと判断し、別のものを試すことにした。

あわせて読みたい

jQueryでオシャレかつ機能的なフォーム画面を実装 formly.js - TechNotejQueryでオシャレかつ機能的なフォーム画面を実装 formly.js - TechNote

社内システムだったら必ずフォームのPost送信は多用するし、Webサイトであっても入力画面が存在するところには必ずフォームは必要となる。そんなとき、簡単にオシャ...

BootStrap 向けのdatepickerによるカレンダー実装は簡単便利 だけどieには不向きか - TechNoteBootStrap 向けのdatepickerによるカレンダー実装は簡単便利 だけどieには不向きか - TechNote

BootStrap向けのdatepickerによるカレンダー実装が簡単かつ便利だったので使用方法をメモ。1.ダウンロード現在はちゃんと日本語対応版も出ているよう...

jQueryで簡単にフワッと画像を表示させる lazyload.jsの実装方法 - TechNotejQueryで簡単にフワッと画像を表示させる lazyload.jsの実装方法 - TechNote

よくWebサイト上で見かける、画面をスクロールしていくとフワッと画像が現れてくるあの小技です。いつか自分も使う機会があったら使ってみようと思っていましたが、本日...

参考元

http://black-flag.net/devel/jQueryFullWideSlider/jQueryFullWideSliderEasingPlus/
http://black-flag.net/jquery/20121219-4407.html


jQueryデザインブック 仕事で絶対に使うプロのテクニック

jQueryデザインブック 仕事で絶対に使うプロのテクニック

jQuery本格入門 ?JavaScript開発・デザイン効率化の基礎から Ajax・QUnitまで

jQuery本格入門 ?JavaScript開発・デザイン効率化の基礎から Ajax・QUnitまで

広告を非表示にする