以前も当ブログでjQueryを使ったループスライダーを紹介しましたが
フリック(ドラッグ)操作が実装されていませんでした。

ループスライダーにフリック(ドラッグ)動作が実装されたパターンはわりと需要があるのに
そのような仕様のプラグイン等はあまり一般的に公開されていないようだったので、
以前紹介したスクリプトを改良してフリック(ドラッグ)動作を実装した
ループスライダーを作成したので紹介してみます。

jQueryでフリック(ドラッグ)可能な要素が流れ続けるループスライダーを実装する方法

「jQueryでフリック(ドラッグ)可能な要素が流れ続けるループスライダーを実装する方法」サンプルを別枠で表示

Webページに並べられた要素が右から左へ流れ続けるループスライダーで
スライダーをフリック(ドラッグ)することができます。

動作自体はただひたすら要素が流れ続けるシンプルなものです。

全体構成についてまずはHTMLから。

◆HTML
<div class="loopSlider">
<ul>
<li><a href="http://www.black-flag.net/"><img src="img/photo1.jpg" alt=""></a></li>
<li><a href="https://www.google.co.jp/"><img src="img/photo2.jpg" alt=""></a></li>
<li><a href="https://www.yahoo.co.jp/"><img src="img/photo3.jpg" alt=""></a></li>
<li><img src="img/photo4.jpg" alt=""></li>
<li><img src="img/photo5.jpg" alt=""></li>
<li><img src="img/photo6.jpg" alt=""></li>
<li><img src="img/photo7.jpg" alt=""></li>
<li><img src="img/photo8.jpg" alt=""></li>
<li><img src="img/photo9.jpg" alt=""></li>
<li><img src="img/photo10.jpg" alt=""></li>
</ul>
</div><!--/.loopSlider-->

スライド動作させる要素は<ul>を使ってリストで構成し
そのリスト全体は任意のブロック要素で囲います。

リストの中の要素にリンクを貼ることも当然のことながら可能になっているので
動作サンプルとして最初の3つのリストのみ<a>タグを設定しています。
不要な場合は外してしまって問題ありません。

この要素に対してCSSは以下のように指定します。

◆CSS
/* ------------------------------
   loopSlider
------------------------------ */
.loopSliderWrap {
	top: 0;
	left: 0;
	height: 300px;
	overflow: hidden;
	position: absolute;
}

.loopSliderWrap:after {
	content: "";
	display: block;
	clear: both;
}

.loopSlider {
	margin: 0 auto;
	width: 100%;
	height: 300px;
	text-align: left;
	position: relative;
	overflow: hidden;
	visibility: hidden;
}

.loopSlider ul {
	height: 300px;
	float: left;
	overflow: hidden;
}

.loopSlider ul li {
	width: 300px;
	height: 300px;
	float: left;
	overflow: hidden;
}

.loopSlider ul li img {
	width: 100%;
	height: 100%;
}

@media only screen and (max-width: 768px) {
	.loopSliderWrap,
	.loopSlider,
	.loopSlider ul {
		height: 100px;
	}

	.loopSlider ul li {
		width: 100px;
		height: 100px;
	}
}

一番最初にある「.loopSliderWrap」は
スクリプト側から生成するブロック要素になり
このセレクタに対しては表示するスライダーの高さを指定しておきます。

HTML側でリスト全体を囲んだブロック要素「.loopSlider」には
要素がスライドする際の、表示する領域の幅と高さを指定します。

メディアクエリーではSP時のループスライダーのサイズを指定します。

そして、実際のフリック(ドラッグ)動作付きのループスライダースクリプトは
以下の様になります。

◆SCRIPT
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
<script>
$(function(){
	let setElm = $('.loopSlider'),
	moveInterval = 3,
	slideTimeBase = 10,
	spWidth = 768,
	spSpeed = 3;

	$(window).on('load', function(){
		setElm.each(function(){
			let self = $(this),
			selfWidth = self.innerWidth(),
			findUl = self.find('ul'),
			findLi = findUl.find('li'),
			findLink = findLi.find('a'),
			listCount = findLi.length;

			listWidth = findLi.outerWidth();
			loopWidth = listWidth * listCount;

			findUl.wrapAll('<div class="loopSliderWrap" />');
			let selfWrap = self.find('.loopSliderWrap');

			setElm.css({visibility:'visible',opacity:'0'}).animate({opacity:'1'},500);

			if(loopWidth > selfWidth){
				findUl.css({width:loopWidth}).clone().appendTo(selfWrap).clone().prependTo(selfWrap);

				selfWrap.css({left:'-' + loopWidth + 'px'});

				setSlideTime();
				timerLeft();

				$(window).on('resize', function(){
					clearInterval(setTimer);
					setSlideTime();
					timerLeft();
				}).resize();

				function setSlideTime() {
					if(window.innerWidth > spWidth){
						slideTime = slideTimeBase;
					} else {
						slideTime = slideTimeBase*spSpeed;
					}
				}

				function timerLeft(){
					setTimer = setInterval(function(){loopPositionLeft()},slideTime);
				};

				function loopPositionLeft(){
					listWidth = findLi.outerWidth();
					loopWidth = listWidth * listCount;

					self.find('ul').css({width:loopWidth});
					selfWrap.css({width:loopWidth*3}).stop().animate({left:'-=' + (moveInterval) + 'px'},slideTime,'linear',function(){
						let posLeft = parseInt(selfWrap.css('left')),
						widthCal = (loopWidth)-((loopWidth)*3);
						if (posLeft <= widthCal) {
							let calCat = posLeft - widthCal;
							//alert(calCat)
							selfWrap.css({left:'-' + (loopWidth - calCat) + 'px'});
						}
					});
					return false;
				};

				function myHandler(e){
					e.preventDefault();
				}

				let isTouch = ('ontouchstart' in window),
				ua = navigator.userAgent;

				selfWrap.on({
					'touchstart mousedown': function(e){
						if(!(ua.search(/iPhone/) != -1 || ua.search(/iPad/) != -1 || ua.search(/Macintosh/) != -1 && 'ontouchend' in document || ua.search(/iPod/) != -1 || ua.search(/Android/) != -1)){
							e.preventDefault();
							$(this).find('a').off('click', myHandler);
						}
						if(selfWrap.is(':animated')){
							clearInterval(setTimer);
						}
						this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX);
						this.leftBegin = parseInt($(this).css('left'));
						this.left = parseInt($(this).css('left'));
						this.touched = true;
					},
					'touchmove mousemove': function(e){
						if(!this.touched){return;}
						if(!(ua.search(/iPhone/) != -1 || ua.search(/iPad/) != -1 || ua.search(/Macintosh/) != -1 && 'ontouchend' in document || ua.search(/iPod/) != -1 || ua.search(/Android/) != -1)){
							e.preventDefault();
							$(this).find('a').on('click', myHandler);
						}
						if(selfWrap.is(':animated')){
							clearInterval(setTimer);
						}
						this.left = this.left - (this.pageX - (isTouch ? event.changedTouches[0].pageX : e.pageX) );
						this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX);
						$(this).css({left:this.left});
					},
					'touchend mouseup mouseout': function(e){
						if (!this.touched) {return;}
						this.touched = false;

						outLeft = parseInt($(this).css('left'));
						if(outLeft < (loopWidth)-((loopWidth)*3)){
							$(this).css({left: outLeft - (loopWidth-(loopWidth*2)) + 'px'});
						}
						if(outLeft > (loopWidth)-((loopWidth)*2)){
							$(this).css({left: outLeft + (loopWidth-(loopWidth*2)) + 'px'});
						}

						timerLeft();
						return false;
					}
				});

				if(ua.search(/iPhone/) != -1 || ua.search(/iPad/) != -1 || ua.search(/Macintosh/) != -1 && 'ontouchend' in document || ua.search(/iPod/) != -1 || ua.search(/Android/) != -1){
					selfWrap.find('a').on({
						'touchstart': function(e){
							thisHref = $(this).attr('href');
							thisTarget = $(this).attr('target');
							touchFlag = true;
						},
						'touchmove': function(e){
							touchFlag = false;
							e.preventDefault();
						},
						'touchend': function(e){
							if(touchFlag == true){
								if(thisTarget == '_blank'){
									window.open(thisHref, '_blank');
								} else {
									location.href = thisHref;
								}
							}
						}
					});
				}
			}
		});
	});
});
</script>

スクリプト開始部分にある設定値の内容は以下の様になっています。

setElm = $(‘.loopSlider’) スライド全体を囲うブロック要素(IDでも可)
moveInterval = 3 スライダーが進む距離
slideTimeBase = 10 moveIntervalで設定した距離を進む時間
spWidth = 768 SPサイズに変わる幅
spSpeed = 3 SPサイズになった際のスライド時間

「moveInterval」スライダーが一度に進む距離(px)になっており、
「slideTimeBase」が「moveInterval」で指定した距離を進むスピードの設定になり、
この2つの値でループスライダーのスピードを調整します。

「spWidth」はSPサイズに変わるウィンドウサイズの幅を指定し、
「spSpeed」ではPCサイズとSPサイズでのリストサイズの割合を指定してスピードを調整します。
サンプルではSP時のループスライダーのリストはPC時のリストの三分の一のサイズにしているので
ここでは「3」を指定しています。

少々、スピードの設定が特殊な作りになってしまっていますが、
これらの値を変更することでループスライダーの
スピード調整ができるようになっています。

以上がフリック(ドラッグ)可能な要素が流れ続けるループスライダーを実装する方法でした。

SP用としてループスライダーを設置する場合は
フリック(ドラッグ)操作はほぼ必須になってくるので
このようなレスポンシブ対応したループスライダーはお役立ていただけるかと思っています。

フリック(ドラッグ)可能なループスライダーを設置する際にぜひ。。。

サンプルファイルをダウンロードしたい方はこちらから

  • このエントリーをはてなブックマークに追加
BlackFlag
FOLLOW

Related Posts

Comments (0)







コメント内容

※コメントにHTMLタグを直接入力しないでください。
※HTMLタグを入力する際はタグ一つ一つの括弧「<」「>」を全角に変換して入力してください。
コメントは承認制になっているのですぐには反映されません。コメント頂いた内容については出来る限り早めの対応を心掛けていますが、時期によって返答が遅くなってしまうことがありますので、何卒ご了承ください。
» コメントについてのご注意  |  » ライセンスに関して

jQueryでフリック(ドラッグ)可能な要素が流れ続けるループスライダーを実装する方法

Hatena Bookmark
Popular Entries
Recent Entries
Animal Protection
  • 福島被曝牛支援のお願い
  • NO FUR
Books
Partner