文章出處

前面的話

當元素內容溢出元素尺寸范圍時,會出現滾動條。但由于滾動條在各瀏覽器下表現不同,兼容性不好。所以,模擬滾動條也是很常見的應用。本文將詳細介紹滾動條模擬

 

原理介紹

滾動條模擬實際上和元素模擬拖拽類似。僅僅通過范圍限定,使元素只可以在單一方向上拖拽

<div id="box" style="height: 200px;width: 16px;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
 <div id="test" style="height: 60px;width: 16px;background-color:#555;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
</div>
<script>
function addEvent(target,type,handler){
 if(target.addEventListener){
 target.addEventListener(type,handler,false);
 }else{
 target.attachEvent('on'+type,function(event){
 return handler.call(target,event);
 });
 }
}
(function(){
 var y0,y1,isMoving;
 var ele = document.getElementById('test');

 var mousedownHandler = function(e){
 e = e  event;
 y0 = ele.offsetTop;
 y1 = e.clientY;
 //按下鼠標時,表示正在運動
 isMoving = true;
 }
 var mousemoveHandler = function(e){
 //如果沒有觸發down事件,而直接觸發move事件,則函數直接返回
 if(!isMoving){
 return;
 }
 e = e  event;
 var y2 = e.clientY; 
 var Y = y0 + (y2 - y1);
 if(Y < 0){Y = 0;}
 var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
 if(Y > YMax){Y = YMax;}
 ele.style.top = Y + 'px';
 }
 var mouseupHandler = function(e){
 //鼠標抬起時,表示停止運動
 isMoving = false;
 //釋放全局捕獲
 if(ele.releaseCapture){
 ele.releaseCapture();
 } 
 }
 var preventDefaultHandler = function(e){
 e = e  event;
 if(e.preventDefault){
 e.preventDefault();
 }else{
 e.returnValue = false;
 }
 //IE8-瀏覽器阻止默認行為
 if(ele.setCapture){
 ele.setCapture();
 }
 }
 addEvent(ele,'mousedown',mousedownHandler);
 addEvent(ele,'mousedown',preventDefaultHandler);
 addEvent(document,'mousemove',mousemoveHandler);
 addEvent(document,'mouseup',mouseupHandler);

})();
</script> 

通過將上面代碼封裝成函數,可以實現橫向和縱向兩種滾動條

<div id="box1" style="height: 200px;width: 16px;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
 <div id="test1" style="height: 60px;width: 16px;background-color:#555;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
</div>
<div id="box2" style="height: 16px;width: 200px;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
 <div id="test2" style="height: 16px;width: 60px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
</div>
<script>
function addEvent(target,type,handler){
 if(target.addEventListener){
 target.addEventListener(type,handler,false);
 }else{
 target.attachEvent('on'+type,function(event){
 return handler.call(target,event);
 });
 }
}
function scrollbar(ele,str){
 var x0,x1,y0,y1,isMoving;

 var mousedownHandler = function(e){
 e = e  event;
 x0 = ele.offsetLeft;
 y0 = ele.offsetTop;
 x1 = e.clientX;
 y1 = e.clientY;
 //按下鼠標時,表示正在運動
 isMoving = true;
 }
 var mousemoveHandler = function(e){
 //如果沒有觸發down事件,而直接觸發move事件,則函數直接返回
 if(!isMoving){
 return;
 }
 e = e  event;
 if(str == 'x'){
 var x2 = e.clientX; 
 var X = x0 + (x2 - x1);
 if(X < 0){X = 0;}
 var XMax = parseInt(ele.parentNode.clientWidth) - ele.offsetWidth;
 if(X > XMax){X = XMax;}
 ele.style.left = X + 'px'; 
 }else{
 var y2 = e.clientY; 
 var Y = y0 + (y2 - y1);
 if(Y < 0){Y = 0;}
 var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
 if(Y > YMax){Y = YMax;}
 ele.style.top = Y + 'px'; 
 }

 }
 var mouseupHandler = function(e){
 //鼠標抬起時,表示停止運動
 isMoving = false;
 //釋放全局捕獲
 if(ele.releaseCapture){
 ele.releaseCapture();
 } 
 }
 var preventDefaultHandler = function(e){
 e = e  event;
 if(e.preventDefault){
 e.preventDefault();
 }else{
 e.returnValue = false;
 }
 //IE8-瀏覽器阻止默認行為
 if(ele.setCapture){
 ele.setCapture();
 }
 }
 addEvent(ele,'mousedown',mousedownHandler);
 addEvent(ele,'mousedown',preventDefaultHandler);
 addEvent(document,'mousemove',mousemoveHandler);
 addEvent(document,'mouseup',mouseupHandler);

};

scrollbar(test1);
scrollbar(test2,'x');
</script> 

應用

下面來介紹通過滾動條實現的幾個應用

數字加減

通過移動滾動條來實現數字的加減。比例關系為:

滾動條已移動距離/滾動條可移動距離= 數字當前值/數字最大值
<div id="box" style="height: 16px;width: 200px;display:inline-block;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
 <div id="test" style="height: 16px;width: 60px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
</div>
<span id="result">0</span>
<script>
function addEvent(target,type,handler){
 if(target.addEventListener){
 target.addEventListener(type,handler,false);
 }else{
 target.attachEvent('on'+type,function(event){
 return handler.call(target,event);
 });
 }
}
function scrollbar(ele,str,max){
 var x0,x1,y0,y1,isMoving,radio;

 var mousedownHandler = function(e){
 e = e  event;
 x0 = ele.offsetLeft;
 y0 = ele.offsetTop;
 x1 = e.clientX;
 y1 = e.clientY;
 //按下鼠標時,表示正在運動
 isMoving = true;
 //x軸方向
 if(str == 'x'){
 ratio = max/(ele.parentNode.offsetWidth - ele.offsetWidth);
 //否則為y軸方向
 }else{
 var disY = e.clientY - ele.offsetTop;
 ratio =max/(ele.parentNode.offsetHeight - ele.offsetHeight);
 }
 }
 var mousemoveHandler = function(e){
 //如果沒有觸發down事件,而直接觸發move事件,則函數直接返回
 if(!isMoving){
 return;
 }
 e = e  event;
 if(str == 'x'){
 var x2 = e.clientX; 
 var X = x0 + (x2 - x1);
 if(X < 0){X = 0;}
 var XMax = parseInt(ele.parentNode.clientWidth) - ele.offsetWidth;
 if(X > XMax){X = XMax;}
 ele.style.left = X + 'px'; 
 result.innerHTML = Math.round(ratio * X);
 }else{
 var y2 = e.clientY; 
 var Y = y0 + (y2 - y1);
 if(Y < 0){Y = 0;}
 var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
 if(Y > YMax){Y = YMax;}
 ele.style.top = Y + 'px';
 result.innerHTML = Math.round(ratio * Y); 
 }

 }
 var mouseupHandler = function(e){
 //鼠標抬起時,表示停止運動
 isMoving = false;
 //釋放全局捕獲
 if(ele.releaseCapture){
 ele.releaseCapture();
 } 
 }
 var preventDefaultHandler = function(e){
 e = e  event;
 if(e.preventDefault){
 e.preventDefault();
 }else{
 e.returnValue = false;
 }
 //IE8-瀏覽器阻止默認行為
 if(ele.setCapture){
 ele.setCapture();
 }
 }
 addEvent(ele,'mousedown',mousedownHandler);
 addEvent(ele,'mousedown',preventDefaultHandler);
 addEvent(document,'mousemove',mousemoveHandler);
 addEvent(document,'mouseup',mouseupHandler);

};

scrollbar(test,'x',100);
</script> 

元素尺寸

通過拖動滾動條來實現元素尺寸的變化,以改變元素寬度為例。比例關系為:

滾動條已移動距離/滾動條可移動距離= 元素當前寬度/元素最大寬度
<div id="box" style="height: 16px;width: 200px;display:inline-block;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
 <div id="test" style="height: 16px;width: 60px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
</div>
<span id="result" style="width: 1px;height: 50px;background-color:pink;display:inline-block;"></span>
<script>
function addEvent(target,type,handler){
 if(target.addEventListener){
 target.addEventListener(type,handler,false);
 }else{
 target.attachEvent('on'+type,function(event){
 return handler.call(target,event);
 });
 }
}
function scrollbar(ele,str,max){
 var x0,x1,y0,y1,isMoving,radio;

 var mousedownHandler = function(e){
 e = e  event;
 x0 = ele.offsetLeft;
 y0 = ele.offsetTop;
 x1 = e.clientX;
 y1 = e.clientY;
 //按下鼠標時,表示正在運動
 isMoving = true;
 //x軸方向
 if(str == 'x'){
 ratio = max/(ele.parentNode.offsetWidth - ele.offsetWidth);
 //否則為y軸方向
 }else{
 var disY = e.clientY - ele.offsetTop;
 ratio =max/(ele.parentNode.offsetHeight - ele.offsetHeight);
 }
 }
 var mousemoveHandler = function(e){
 //如果沒有觸發down事件,而直接觸發move事件,則函數直接返回
 if(!isMoving){
 return;
 }
 e = e  event;
 if(str == 'x'){
 var x2 = e.clientX; 
 var X = x0 + (x2 - x1);
 if(X < 0){X = 0;}
 var XMax = parseInt(ele.parentNode.clientWidth) - ele.offsetWidth;
 if(X > XMax){X = XMax;}
 ele.style.left = X + 'px'; 
 result.style.width = Math.round(ratio * X) + 'px';
 }else{
 var y2 = e.clientY; 
 var Y = y0 + (y2 - y1);
 if(Y < 0){Y = 0;}
 var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
 if(Y > YMax){Y = YMax;}
 ele.style.top = Y + 'px';
 result.style.width = Math.round(ratio * Y) + 'px'; 
 }

 }
 var mouseupHandler = function(e){
 //鼠標抬起時,表示停止運動
 isMoving = false;
 //釋放全局捕獲
 if(ele.releaseCapture){
 ele.releaseCapture();
 } 
 }
 var preventDefaultHandler = function(e){
 e = e  event;
 if(e.preventDefault){
 e.preventDefault();
 }else{
 e.returnValue = false;
 }
 //IE8-瀏覽器阻止默認行為
 if(ele.setCapture){
 ele.setCapture();
 }
 }
 addEvent(ele,'mousedown',mousedownHandler);
 addEvent(ele,'mousedown',preventDefaultHandler);
 addEvent(document,'mousemove',mousemoveHandler);
 addEvent(document,'mouseup',mouseupHandler);

};

scrollbar(test,'x',100);
</script>

內容滾動

通過拖動滾動條來實現內容滾動,比例關系為:

滾動條已移動距離/滾動條可移動距離= 內容已移動距離/內容可移動距離
<div id="box" style="height: 200px;width: 16px;display:inline-block;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;vertical-align:middle;">
 <div id="test" style="height: 60px;width: 16px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
</div>
<span id="result" style="width: 100px;height: 200px;background-color:pink;display:inline-block;line-height:30px;vertical-align:middle;position:relative;overflow:hidden;"><div id="resultIn" style="position:absolute;top:0;">測試文字<br>測試文字<br>測試文字<br>測試文字<br>測試文字<br>測試文字<br>測試文字<br>測試文字<br>測試文字<br>測試文字<br>測試文字<br>測試文字<br></div></span>
<script>
function addEvent(target,type,handler){
 if(target.addEventListener){
 target.addEventListener(type,handler,false);
 }else{
 target.attachEvent('on'+type,function(event){
 return handler.call(target,event);
 });
 }
}
function scrollbar(ele,str,max){
 var x0,x1,y0,y1,isMoving,radio;
 var max = result.offsetHeight - resultIn.offsetHeight;
 var mousedownHandler = function(e){
 e = e  event;
 x0 = ele.offsetLeft;
 y0 = ele.offsetTop;
 x1 = e.clientX;
 y1 = e.clientY;
 //按下鼠標時,表示正在運動
 isMoving = true;
 //x軸方向
 if(str == 'x'){
 ratio = max/(ele.parentNode.offsetWidth - ele.offsetWidth);
 //否則為y軸方向
 }else{
 var disY = e.clientY - ele.offsetTop;
 ratio =max/(ele.parentNode.offsetHeight - ele.offsetHeight);
 }
 }
 var mousemoveHandler = function(e){
 //如果沒有觸發down事件,而直接觸發move事件,則函數直接返回
 if(!isMoving){
 return;
 }
 e = e  event;
 if(str == 'x'){
 var x2 = e.clientX; 
 var X = x0 + (x2 - x1);
 if(X < 0){X = 0;}
 var XMax = parseInt(ele.parentNode.clientWidth) - ele.offsetWidth;
 if(X > XMax){X = XMax;}
 ele.style.left = X + 'px'; 
 resultIn.style.left = Math.round(ratio * X) + 'px';
 }else{
 var y2 = e.clientY; 
 var Y = y0 + (y2 - y1);
 if(Y < 0){Y = 0;}
 var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
 if(Y > YMax){Y = YMax;}
 ele.style.top = Y + 'px';
 resultIn.style.top = Math.round(ratio * Y) + 'px'; 
 }

 }
 var mouseupHandler = function(e){
 //鼠標抬起時,表示停止運動
 isMoving = false;
 //釋放全局捕獲
 if(ele.releaseCapture){
 ele.releaseCapture();
 } 
 }
 var preventDefaultHandler = function(e){
 e = e  event;
 if(e.preventDefault){
 e.preventDefault();
 }else{
 e.returnValue = false;
 }
 //IE8-瀏覽器阻止默認行為
 if(ele.setCapture){
 ele.setCapture();
 }
 }
 addEvent(ele,'mousedown',mousedownHandler);
 addEvent(ele,'mousedown',preventDefaultHandler);
 addEvent(document,'mousemove',mousemoveHandler);
 addEvent(document,'mouseup',mouseupHandler);

};

scrollbar(test);
</script>


文章列表


不含病毒。www.avast.com
文章標籤
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣(0)