小金井にあるWEB制作会社の備忘録

MEMORANDUM

jQuerでフリック(ドラッグ)スライダーを実装

PC、スマホともにフリック(ドラッグ)できる自動送り式のイメージスライダーを実装した時のソースをメモ。
idを取得して、id毎に作動するのでページ内にいくつでも設置可能。

HTML

<figure class="imageslider" id="areai_d">
<div class="imageslider__frame">
<ul class="imageslider__frame__slides">
<li><img src="画像URL" ondragstart="return false"></li>
<li><img src="画像URL" ondragstart="return false"></li>
<li><img src="画像URL" ondragstart="return false"></li>
</ul>
</div>
<nav class="imageslider__nav">
<ol>
</ol>
</nav>
</figure>

「ondragstart」属性の設定は「firefox」対策。

CSS

.imageslider .imageslider__frame {
	width: 100%;
	height: -webkit-calc(100% - 40px) ;
	height: calc(100% - 40px) ;
	position: relative;
	overflow: hidden;
}
.imageslider .imageslider__frame .imageslider__frame__slides {
	display: -webkit-flex;
	display: flex;
}
.imageslider .imageslider__frame .imageslider__frame__slides li img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.imageslider .imageslider__nav {
	margin: 25px 0 0;
}
.imageslider .imageslider__nav ol {
	display: -webkit-flex;
	display: flex;
}
.imageslider .imageslider__nav li {
	width: 65px;
	margin: 0 5px;
}
.imageslider .imageslider__nav li a {
	background: #eee;
	width: auto;
	height: 15px;
	display: block;
}
.imageslider .imageslider__nav li a.active {
	background: #916f22;
}

jQuery

var target = [];
var size = [];
var divFW = [];
var startMargin = [];
var listblock = [];
var listposition = [];
var listpositionmax = [];
var leftposition = [];
	
for(i = 0; i < $('.imageslider').length; i++){
	target[i] =$('.imageslider').eq(i).attr('id');
	size[target[i]] = $('#'+target[i]+' .imageslider__frame .imageslider__frame__slides li').length;
	divFW[target[i]] = $('#'+target[i]+' .imageslider__frame').width();
	startMargin[target[i]] = size[target[i]]*divFW[target[i]];

	$('#'+target[i]+' .imageslider__frame .imageslider__frame__slides').css({'width':size[target[i]]*divFW[target[i]]*3+'px', 'margin-left':'-'+startMargin[target[i]]+'px'});
	$('#'+target[i]+' .imageslider__frame .imageslider__frame__slides li').css({'width':divFW[target[i]]+'px'});
	listblock[i] = $('#'+target[i]+' .imageslider__frame .imageslider__frame__slides').find('li');
	listblock[i].clone().appendTo('#'+target[i]+' .imageslider__frame .imageslider__frame__slides');
	listblock[i].clone().prependTo('#'+target[i]+' .imageslider__frame .imageslider__frame__slides');
	var li = [];
	for (var j = 0; j < size[target[i]]; j++){
		li.push('<li><a href=""></a></li>');
	}
	$('#'+target[i]+' .imageslider__nav ol').html(li);
	$('#'+target[i]+' .imageslider__nav ol li:first-of-type a').addClass('active');
	listposition[target[i]] = 0 + startMargin[target[i]];
	listpositionmax[target[i]] = divFW[target[i]]*(size[target[i]]-1) + startMargin[target[i]];
}
	
$('.imageslider__nav li a').click(function(){
	var id = $(this).parents('.imageslider').attr('id');
	$('#'+id+' .imageslider__nav li a').removeClass('active');
	$(this).addClass('active');
	var index = $(this).parent('li').index();
	$('#'+id+' .imageslider__frame__slides').animate({'margin-left':startMargin[id]*(-1)-index*divFW[id]+'px'}, 'slow', 'swing');
	listposition[id] = Number(index*divFW[id]);
	return false;
});

//PCでのマウス操作
if($(window).width() > 980){
	$('.imageslider .imageslider__frame__slides').mousedown(function(e){
		this.touchX = event.pageX;
		this.slideX = $(this).position().left;
		$('.imageslider .imageslider__frame__slides').mousemove(function(e){
			e.preventDefault();
			this.slideX = this.slideX - (this.touchX - event.pageX );
			$(this).css({left:this.slideX});
			this.accel = (event.pageX - this.touchX) * 5;
			this.touchX = event.pageX;
		});
	}).mouseup(function(e){
		var id = $(this).parents('.imageslider').attr('id');
		edge = this.slideX % divFW[id];
				
		leftposition[id] = parseInt($('#'+id+' .imageslider__frame__slides').css('margin-left'),10)*(-1);
		if(edge <= 0){
			if(leftposition[id] < listpositionmax[id]){
				$('#'+id+' .imageslider__frame__slides').animate({'margin-left':'-='+divFW[id]+'px'}, 'slow', 'swing');
				listposition[id] = listposition[id]+divFW[id];
				$('#'+id+' .imageslider__nav li a.active').parent('li').next().addClass('next');
				$('#'+id+' .imageslider__nav li a').removeClass('active');
				$('#'+id+' .imageslider__nav li.next a').addClass('active');
				$('#'+id+' .imageslider__nav li').removeClass('next');
			}else{
				$('#'+id+' .imageslider__frame__slides').animate({'margin-left':'-='+divFW[id]+'px'}, 'slow', 'swing', function() {
				$('#'+id+' .imageslider__frame__slides').css({'margin-left':'-'+startMargin[id]+'px'});
				});
				listposition[id] = 0+startMargin[id];
				$('#'+id+' .imageslider__nav ol li a').removeClass('active');
				$('#'+id+' .imageslider__nav ol li:first-of-type a').addClass('active');	
			}
			return false;
		}else{
			if(leftposition[id] > 0 + startMargin[id]){
				$('#'+id+' .imageslider__frame__slides').animate({'margin-left':'+='+divFW[id]+'px'}, 'slow', 'swing');
				listposition[id] = listposition[id]-divFW[id];
				$('#'+id+' .imageslider__nav li a.active').parent('li').prev().addClass('prev');
				$('#'+id+' .imageslider__nav li a').removeClass('active');
				$('#'+id+' .imageslider__nav li.prev a').addClass('active');
				$('#'+id+' .imageslider__nav li').removeClass('prev');
			}else{
				$('#'+id+' .imageslider__frame__slides').animate({'margin-left':'+='+divFW[id]+'px'}, 'slow', 'swing', function() {
					$('#'+id+' .imageslider__frame__slides').css({'margin-left':'-'+listpositionmax[id]+'px'});
					listposition[id] = listpositionmax[id];
					$('#'+id+' .imageslider__nav ol li a').removeClass('active');
					$('#'+id+' .imageslider__nav ol li:last-of-type a').addClass('active');	
				});
			}
			return false;
		}
		$('.imageslider .imageslider__frame__slides').off("mousemove");
	});	
}else{
	//スマホでのフリック操作
	$('.imageslider .imageslider__frame__slides').bind({
		'touchstart': function(e) {
			this.touchX = event.changedTouches[0].pageX;
			this.slideX = $(this).position().left;
		},
		'touchmove': function(e) {
			e.preventDefault();
			this.slideX = this.slideX - (this.touchX - event.changedTouches[0].pageX );
			$(this).css({left:this.slideX});
			this.accel = (event.changedTouches[0].pageX - this.touchX) * 5;
			this.touchX = event.changedTouches[0].pageX;
		},		
		'touchend': function(e){
			var id = $(this).parents('.imageslider').attr('id');
			edge = this.slideX % divFW[id];
				
			leftposition[id] = parseInt($('#'+id+' .imageslider__frame__slides').css('margin-left'),10)*(-1);
			if(edge <= 0){
				if(leftposition[id] < listpositionmax[id]){
					$('#'+id+' .imageslider__frame__slides').animate({'margin-left':'-='+divFW[id]+'px'}, 'slow', 'swing');
					listposition[id] = listposition[id]+divFW[id];
					$('#'+id+' .imageslider__nav li a.active').parent('li').next().addClass('next');
					$('#'+id+' .imageslider__nav li a').removeClass('active');
					$('#'+id+' .imageslider__nav li.next a').addClass('active');
					$('#'+id+' .imageslider__nav li').removeClass('next');
				}else{
					$('#'+id+' .imageslider__frame__slides').animate({'margin-left':'-='+divFW[id]+'px'}, 'slow', 'swing', function() {
					$('#'+id+' .imageslider__frame__slides').css({'margin-left':'-'+startMargin[id]+'px'});
					});
					listposition[id] = 0+startMargin[id];
					$('#'+id+' .imageslider__nav ol li a').removeClass('active');
					$('#'+id+' .imageslider__nav ol li:first-of-type a').addClass('active');	
				}
				return false;
			}else{
				if(leftposition[id] > 0 + startMargin[id]){
					$('#'+id+' .imageslider__frame__slides').animate({'margin-left':'+='+divFW[id]+'px'}, 'slow', 'swing');
					listposition[id] = listposition[id]-divFW[id];
					$('#'+id+' .imageslider__nav li a.active').parent('li').prev().addClass('prev');
					$('#'+id+' .imageslider__nav li a').removeClass('active');
					$('#'+id+' .imageslider__nav li.prev a').addClass('active');
					$('#'+id+' .imageslider__nav li').removeClass('prev');
				}else{
					$('#'+id+' .imageslider__frame__slides').animate({'margin-left':'+='+divFW[id]+'px'}, 'slow', 'swing', function() {
						$('#'+id+' .imageslider__frame__slides').css({'margin-left':'-'+listpositionmax[id]+'px'});
						listposition[id] = listpositionmax[id];
						$('#'+id+' .imageslider__nav ol li a').removeClass('active');
						$('#'+id+' .imageslider__nav ol li:last-of-type a').addClass('active');
					});
				}
				return false;
			}
		}
	});
}
	
//自動スライド処理
setInterval(function(){
	for(i = 0; i < $('.imageslider').length; i++){
		target[i] =$('.imageslider').eq(i).attr('id');
		if(listposition[target[i]] < listpositionmax[target[i]]){
			$('#'+target[i]+' .imageslider__frame__slides').animate({'margin-left':'-='+divFW[target[i]]+'px'}, 'slow', 'swing');
			listposition[target[i]] = listposition[target[i]]+divFW[target[i]];
			$('#'+target[i]+' .imageslider__nav li a.active').parent('li').next().addClass('next');
			$('#'+target[i]+' .imageslider__nav li a').removeClass('active');
			if($('#'+target[i]+' .imageslider__nav li.next').length > 0){
				$('#'+target[i]+' .imageslider__nav li.next a').addClass('active');
				$('#'+target[i]+' .imageslider__nav li').removeClass('next');
			}else{
				$('#'+target[i]+' .imageslider__nav li:first-of-type a').addClass('active');
			}
		}else{
			$('#'+target[i]+' .imageslider__frame__slides').css({'margin-left':'-'+Number(startMargin[target[i]]-divFW[target[i]])+'px'}).animate({'margin-left':'-='+divFW[target[i]]+'px'}, 'slow', 'swing');
			listposition[target[i]] = 0+startMargin[target[i]];
			$('#'+target[i]+' .imageslider__nav ol li a').removeClass('active');
			$('#'+target[i]+' .imageslider__nav ol li:first-of-type a').addClass('active');
		}
	}
}, 5000); //数字は時間設定5000=5秒