1. 程式人生 > >JS原生之----滾動條

JS原生之----滾動條

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>滾動條</title>
		<style>
        * {margin: 0;padding: 0;}
        html,body {width: 100%;height: 100%;}
        #box { width: 100%; height: 100%; overflow: hidden; }
        .ball { width: 100%; height: 500px; }
        #scroll {
            width: 6px; height: 96%;
            position: fixed; top: 2%; right: 5px;
            border-radius: 3px; background-color: rgba(235, 233, 233, 0.5);
            z-index: 9998; opacity: 0;
        }
        #scrollBar {
            position: absolute; left: 0; top: 0;
            z-index: 9999;
            width: 6px; height: 20px;
            border-radius: 3px;
            background-color: #383838;
        }
    </style>
	</head>
	<body style="overflow:hidden;">
    <div id="box">
        <div id="content">
             <p class="ball" style="background-color:red;">贊</p>
            <p class="ball" style="background-color:blue;">玉</p>
            <p class="ball" style="background-color:yellow;">米</p>
            <p class="ball" style="background-color:green;">欣</p>
            <p class="ball" style="background-color:gray;">評</p>
            <p class="ball" style="background-color:orange;">輪</p>
            <p class="ball" style="background-color:pink;">吧</p>
        </div>
    </div>
    <div id="scroll">
        <div id="scrollBar"></div>
    </div>
	</body>
	<script type="text/javascript" src="js/draggable.js" ></script>
	<script>
		onload = function(){
			var scrollDiv = document.getElementById("scroll");
			var scrollBar = document.getElementById("scrollBar");
			var content = document.getElementById("content");
			var box = document.getElementById("box");
			
			/*滾輪事件 火狐:DOMMouseScroll(必須用2級事件寫) 其餘:onmousewheel(一級事件,用2級事件寫也可以:mousewheel)
			 * 火狐中:e.detail>0時向下滾動,e.detail<0時向上滾動
			 * 其餘瀏覽器包括IE: e.wheelDelta<0時表示向下滾動,e.wheelDelta>0時向上滾動
			 * 用到的公式:滾動距離/(頁面高-可視視窗高)  == bar距div的top/(滾動條div-滾動條bar)
			 * 程式碼:box.scrollTop/(content.offsetHeight-document.body.offsetHeight)  == scrollBar.style.top/(scrollDiv.offsetHeight - scrollBar.offsetHeight);
			 */
			/*box.addEventListener("mousewheel",function(e){
				e =e||event;
				//console.log(e.wheelDelta);
				if(e.wheelDelta<0){
					box.scrollTop += 50; //滾動的距離
				}else{
					box.scrollTop -=50;
				}
				scrollBar.style.top = box.scrollTop/(content.offsetHeight-document.body.offsetHeight) *(scrollDiv.offsetHeight - scrollBar.offsetHeight)+"px";
				if(box.scrollTop<300){
					scrollDiv.style.opacity = 0;
				}else{
					scrollDiv.style.opacity = 1;
				}
			})
			
			box.addEventListener("DOMMouseScroll",function(e){
				e =e||event;
				//console.log(e.detail);
				if(e.detail>0){
					box.scrollTop +=50;
				}else{
					box.scrollTop -=50;
				}
				//相容document.body.offsetHeight  
				console.log(document.body.offsetHeight);
				scrollBar.style.top = box.scrollTop/(content.offsetHeight-document.body.offsetHeight)*(scrollDiv.offsetHeight - scrollBar.offsetHeight)+"px";
				if(box.scrollTop <300){
					scrollDiv.style.opacity = 0;
				}else{
					scrollDiv.style.opacity = 1;
				}
			})
			*/
			/*
			 * 由上述整理精煉得到如下程式碼:
			 */
			
			function scrollFunc(e){ //e.type :返回的值是mousewheel或是DOMMouseScroll
				e =e||even;
				var d = null;
				if(e.type == "mousewheel"){
					d = e.wheelDelta;
				}else {
					d = -e.detail;
				}
				
				if(d<0){
					box.scrollTop +=50;
				}else{
					box.scrollTop -=50;
				}
				setScroll();
				if(box.scrollTop<300){
					scrollDiv.style.opacity = 0;
				}else{
					scrollDiv.style.opacity = 1;
				}
				
			}
		
		
		box.addEventListener("mousewheel",scrollFunc);
		box.addEventListener("DOMMouseScroll",scrollFunc);
		//當對視窗大小進行調整時
		window.addEventListener("resize",function(e){
			setScroll();
		});			
			function setScroll(){
				scrollBar.style.top = box.scrollTop/(content.offsetHeight-document.body.offsetHeight)*(scrollDiv.offsetHeight - scrollBar.offsetHeight)+"px";
			}
			//點選scrollBar可以拖拽,並且頁面隨之滑動
			draggable(scrollDiv,scrollBar,{x:false},function(){
				box.scrollTop = this.offsetTop *(content.offsetHeight -document.documentElement.offsetHeight)/(scrollDiv.offsetHeight -this.offsetHeight);
			});
			//雙擊回到最頂部
			scrollDiv.addEventListener("dblclick",function(){
				box.scrollTop=0;
				scrollBar.style.top =0;
				
			})
		}
		
		
	</script>
</html>

封裝:draggable.js

/*
*parentObj 父元素範圍
*ele移動物件
*param 想要移動的方向
*/
function draggable(parentObj,ele,param,callback){
//判斷有沒有定位  呼叫getStyle js封裝好的一個函式,獲取樣式
if(getStyle(ele,"position") != "absolute")return ;
	//確定移動方向(給引數設定預設值)
	param = param ||{x:true,y:true};
	if(param.x == false){
		param.x = false;
		param.y = true;
	}
	if(param.y ==false){
		param.x =true;
		param.y =false;
	}
	//讓這個回撥函式成為移動物件的一個函式(不寫這個,callback就是window的)
	ele.callback = callback || function(){};
	//判斷移動的邊界值距左邊  還有上邊的距離(移動的範圍)
	var section ={
		maxLeft :parentObj.offsetWidth - ele.offsetWidth,
		maxTop :parentObj.offsetHeight - ele.offsetHeight
	}
	ele.onmousedown=function(e){
		e = e||event;
		var disX = e.offsetX,disY = e.offsetY;
		document.onmousemove =function(e){
			e = e||event;
			if(param.x){
			//計算拖拽元素在父元素內的座標
			//公式:滑鼠頁面座標 - 滑鼠跟拖拽的父元素的相對座標 - 父元素頁面座標(呼叫函式offset())
				var _left = e.clientX - disX - offset(parentObj).left;	
				//Math.min(_left,section.maxLeft) 當_left > section.maxLeft 時 就相當於出界了,,取最小值就很好的控制了這一點
				_left = (_left<0 ? 0:(Math.min(_left,section.maxLeft))); 
				ele.style.left = _left +"px";
			}
			if(param.y){
				var _top = e.clientY - disY - offset(parentObj).top;
				_top = (_top<0 ? 0:(Math.min(_top,section.maxTop))); 
				ele.style.top = _top +"px";
			}
			//每移動一次,執行一次回撥函式
			ele.callback();
		}
		
	}
	document.onmouseup=function(){
		document.onmousemove =null;		
	}
}

//函式的懶載入 獲取樣式
function getStyle(obj, attr) {
	if(obj.currentStyle) {
		getStyle = function(obj, attr){
			return obj.currentStyle[attr];
		}
		return obj.currentStyle[attr];
	} else {
		getStyle = function(obj, attr){
			return getComputedStyle(obj,null)[attr];
		}
		return getComputedStyle(obj,null)[attr];
	}
}

//獲取一個元素在頁面的絕對位置
function offset(obj) {
	var _left = 0, _top = 0;
	while(obj) {
		_left += obj.offsetLeft;
		_top += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return {left:_left, top: _top};
}