divとJqueryのみで縦スライダー(PC/SPクロスブラウザ)

verticalslider

divとJqueryのみで縦スライダー(ドラッグ、ホイール、スワイプ対応 PC/SPクロスブラウザ)

以前にCSSで縦スライダーを制作 しました。しかしクロスブラウザに対応するためWebKitだらけの長いCSSコードになってしまいました。

それならばとInput type="range"を使わないでJqueryとDivのみで縦スライダーを作ってみました。本当はSP版まで行く予定でしたがテストでサーバーに上げていたらGoogleにINDEXされてしまいまして、取り急ぎPC版までの対応です。

⇒SPも対応してみました。

Sample

50
50

説明

div_jquery_verticalslider

最初にグレー部分と赤い部分でeventをとっていたのですが、mousemoveなどで上下範囲外になりeventをロストします。そこで黒い部分でeventをとりドラッグなどでのeventロスト防いでみました。

クリックmousedown,タップtouchstart,ドラッグmousemove,スワイプtouchmoveに応じて赤い部分の高さを動かし青いポインターを動かしています。

Jquery

var ckon = 0;
var pageY;
$(".bar").bind({
	'mousedown': function(e) { 
		var index = $(".bar").index(this);
		var target_rect = e.currentTarget.getBoundingClientRect();
		var x = e.clientX - target_rect.left;
		var ck = parseInt(e.clientY + 65 - target_rect.top);/*130px/2*/
		ck = ck - 80 ;
		if(ck < 0) ck=0;
		if(ck > 100) ck=100;
		if (x <= 30 && 0 <= ck && ck <= 100){
		$(".sliderVal").eq(index).text((ck-100)*-1);
  	$(".space").eq(index).css('height', ck );
        /*ここに入れてもOK?みたい*/
		$(".mbox").text( "mousedown" );
	}
    ckon=1;
	},
	'touchstart': function(e) { 
		var index = $(".bar").index(this);
		var target_rect = e.currentTarget.getBoundingClientRect();
		var x = e.clientX - target_rect.left;
		var ck = parseInt(e.clientY + 65 - target_rect.top);/*130px/2*/
		ck = ck - 80 ;
		if(ck < 0) ck=0;
		if(ck > 100) ck=100;
		if (x <= 30 && 0 <= ck && ck <= 100){
		$(".sliderVal").eq(index).text((ck-100)*-1);
  	$(".space").eq(index).css('height', ck );
        /*ここに入れてもOK?みたい*/
		$(".mbox").text( "touchstart" );
		$("body").css("overflow","hidden");
		$(window).on('touchmove.noScroll', function(e) {
			e.preventDefault();
		});
	}
    ckon=1;
	},
	'mousemove': function(e) { 
		if (ckon==1){
        var index = $(".bar").index(this);
        var target_rect = e.currentTarget.getBoundingClientRect();
        var x = e.clientX - target_rect.left;
        var ck = parseInt(e.clientY + 65 - target_rect.top);/*130px/2*/
	    ck = ck - 80 ;
	    if(ck < 0) ck=0;
		if(ck > 100) ck=100;
       	if (x <= 30 && 0 <= ck && ck <= 100){
			$(".sliderVal").eq(index).text((ck-100)*-1);
			$(".space").eq(index).css('height', ck );
		}
       }
	},
	'touchmove': function(e) { 

	    $("body").css("overflow","hidden");/*chromeSP*/
		var target_rect = e.currentTarget.getBoundingClientRect();
		var windowpagey =  $(window).scrollTop();
		var index = $(".bar").index(this);
 
		var pageY;
		if (e.originalEvent.touches) {
			pageY = e.originalEvent.touches[0].pageY;
		} else {
			pageY = e.pageY;
	    }
		var ori_point=parseInt(target_rect.top + windowpagey + 65);/*130px/2*/
		pageY= parseInt(pageY);
 
		$(".mbox").text( "原点(真ん中):"+ ori_point + " 指の位置:" + pageY );
		var ck = ori_point - pageY;
		if(ck<0){
			ck = ck*-1 - 1;		  
		}else{
		    ck = ck*-1 + 1;
		}
 
		if (100<ck) ck = 100;
		if (ck < 0) ck = 0;
		$(".space").eq(index).css('height', ck );
 
		$(".sliderVal").eq(index).text((ck-100)*-1);/*safariSP*/
		$(window).on('touchmove.noScroll', function(e) {
			e.preventDefault();
		});

	},
	'mouseenter': function(e) { /*mouseoverダメ内側の要素で反応する*/
		//ckon = 0;
		$("body").css("overflow","hidden");
	},
	'mouseleave': function(e) { /*mouseoutダメ内側の要素で反応する*/
       ckon = 0;
	   $("body").css("overflow","auto");
	},
	'mousewheelevent wheel mousewheel': function(e) {
		var delta = e.originalEvent.deltaY ? -(e.originalEvent.deltaY) : e.originalEvent.wheelDelta ? e.originalEvent.wheelDelta : -(e.originalEvent.detail);
		delta = parseInt(delta);
		var index = $(".bar").index(this);
        //alert(delta);
		var userAgent = window.navigator.userAgent.toLowerCase();
		var ck = parseInt($('.space').eq(index).css('height'));
		/*サファリだけ.css('top')の値が拡大率につられて大きくな為,Divの高さにした*/
        
		if( userAgent.match(/(msie|MSIE)/) || userAgent.match(/(T|t)rident/) ) {
			if (-40 < delta && delta< 0)delta= delta+28;
			if (0<delta && delta <40)delta= delta-28;
			if (delta <-40)delta= -2;
			if (40 < delta)delta= 2;
		} else if(userAgent.indexOf('edge') != -1) {
			if (delta< 0)delta= delta+205;
			if (0<delta)delta= delta-205;
		} else if (userAgent.indexOf('chrome') != -1) {
			if (delta< 0)delta= delta+120;
			if (0<delta)delta= delta-120;
		} else if (userAgent.indexOf('firefox') != -1) {
     
		} else if (userAgent.indexOf('safari') != -1) {
			if (delta< 0)delta= delta+114;
			if (0<delta)delta= delta-114;
			/*wheelの動きが鈍い*/
		} 
		ck = ck+(delta*-1);
        //$(".mbox").text( "スクロール"+ delta);
 
		if (-5 <= ck && ck <= 105){
			if(ck < 0) ck=0;
			if(ck > 100) ck=100;
			$(".sliderVal").eq(index).text((ck-100)*-1);
			$(".space").eq(index).css('height', ck );
		}
		
	},
	'touchend mouseup': function(e) {
		var target_rect = e.currentTarget.getBoundingClientRect();
		var index = $(".bar").index(this);
		var x = e.clientX - target_rect.left;
		var ck = parseInt(e.clientY + 65 - target_rect.top);/*130px/2*/
	    ck = ck - 80 ;
	    if(ck < 0) ck=0;
		if(ck > 100) ck=100;
		if (x <= 30 && 0 <= ck && ck <= 100){
			$(".sliderVal").eq(index).text((ck-100)*-1);
			//ck =  ck + 'px';
			$(".space").eq(index).css('height', ck );
		}
		ckon=0;
		$(".mbox").text( "touchend::mouseup" );
		$(window).off('.noScroll');
		$("body").css("overflow","auto");
	}
});

CSS

.Vertical{
height:150px;
width:30px;
display:inline-block;
text-align:center;
/*border: solid;*/
}

.bar{
margin: 15px;
border-radius: 10px;	
height:130px;
width:30px;
display: table-cell;
vertical-align: middle;
/*background-color:black;*/
}

.bardisp{
margin: 0 auto;
background-color:grey;
border-radius: 5px;	
height:110px;
width:10px;
}
 
.space{
/*background-color:red;*/
height:50px;
}

.point{
background-color:blue;
border-radius: 10px;	
height:10px;
width:10px;
}

html

<h3><span class="color1">Sample</span></h3>
<div class="Vertical">
 <div class="bar">
  <div class="bardisp">
   <div class="space"></div>
   <div class="point"> </div>
  </div>
 </div>
 <output class="sliderVal">50<output>
</div>
     
     
<div class="Vertical">
 <div class="bar">
  <div class="bardisp">
   <div class="space"></div>
   <div class="point"> </div>
  </div>
 </div>
 <output class="sliderVal">50<output>
</div>

<div class="mbox">
</div>
logo