原生JavaScript實現(xiàn)滾動條效果
本文實例講解原生JavaScript實現(xiàn)滾動條效果的相關(guān)代碼,分享給大家供大家參考,具體內(nèi)容如下
原理是對滑動條塊進行監(jiān)聽,按下鼠標按鍵后,監(jiān)聽鼠標移動,然后根據(jù)滑動條塊移動的百分比算出滾動區(qū)域的滾動程度,用marginLeft進行滾動,具體的寫在注釋里。
整體弄成了一個對象,防止各種亂七八糟的數(shù)據(jù)污染全局變量。另外,對象內(nèi)部調(diào)用的函數(shù)也都寫到了對象構(gòu)造函數(shù)的里面,由于對象作用域鏈的原理,外部無法進行調(diào)用,防止不小心在外部調(diào)用。
<!DOCTYPE html>
<html>
<head>
<title>Blank Page for Rich Text Editing</title>
<meta http-equiv="content-type" name="author" content="Fujihara No Kokukiyo" />
<meta charset="utf-8" />
</head>
<style rel="stylesheet" type="text/css">
.outer{width:500px;border:1px solid black;overflow:hidden;margin:50px 0 0 100px;}
.test_div{width:1200px;background-image:linear-gradient(90deg,lightcoral 0%,lightgreen 50%,lightblue 100%);height:150px;}
.slider_bar,.slider_block{ border-radius:5px;}
.slider_bar{position:relative;width:80%;margin:5px auto 5px auto;background-color:lightgreen;height:5px;}
.slider_block{width:20px;height:5px;background-color:grey;cursor:pointer;position:absolute;}
</style>
<script type="text/javascript">
window.onload=function(){
/**
* 滑動條對象構(gòu)造函數(shù),
* 內(nèi)含其他功能性函數(shù),利用函數(shù)作用域鏈的原理,防止自己隨意調(diào)用
* 兼容:firefox、opera、chrome
* ie沒試,然而顯然不兼容舊版本ie(8及之前),因為舊版本ie添加事件監(jiān)聽函數(shù)的方法不同。如若要兼容ie,還需要添加其他函數(shù)
* js生成的滑動條類名為slider_bar、滑動塊類型為slider_block,可用css樣式自己設(shè)置大小、顏色等。
* 滑動條左右padding未限制滑動條界限,如若需要限制,須在計算部分進行細小修改,加算padding,此處略去。
*
* @param {DOMElement} slider_content 被滾動的元素(不是被滾動元素的父元素)
*/
function Slider(slider_content){
//slider_instance為對象本身(在事件處理函數(shù)中會進行訪問,而事件處理函數(shù)中的this對象已被注入為event.currentTarget,因此預(yù)先存儲)
var slider_instance=this;
//this.slider_content為被滾動的元素
this.slider_content=slider_content;
//this.outer為被滾動元素的父元素
this.outer=slider_content.parentNode;
//創(chuàng)建滑動條
this.slider_bar=createSliderBar();
//創(chuàng)建滑動條塊
this.slider_block=createSliderBlock();
//拼裝
this.slider_bar.appendChild(this.slider_block);
this.outer.appendChild(this.slider_bar);
//被滾動元素可被滾動的總寬度
this.slider_content_width=this.slider_content.offsetWidth-this.outer.clientWidth;
//滑動條塊可滑動的總寬度
this.slider_bar_width=this.slider_bar.clientWidth-this.slider_block.offsetWidth;
//被滾動元素的左邊距(相對父元素)
this.slider_content_left=0;
//滾動塊的左邊距(相對父元素)
this.slider_block_left=0;
//滑動條的左邊距(相對視口)
this.slider_bar_pageLeft=getPageLeft(this.slider_bar);
//滑動條塊添加鼠標壓鍵事件
this.slider_block.addEventListener("mousedown",mousedownHandler,false);
//離開父元素后取消鼠標移動事件
this.outer.addEventListener("mouseleave",mouseupHandler,false);
//鼠標彈鍵時取消鼠標移動事件
this.outer.addEventListener("mouseup",mouseupHandler,false);
/**
* 創(chuàng)建滑動條
*/
function createSliderBar(){
var slider_bar=document.createElement("div");
slider_bar.className="slider_bar";
return slider_bar;
}
/**
* 創(chuàng)建滑動條塊
*/
function createSliderBlock(){
var slider_block=document.createElement("div");
slider_block.className="slider_block";
return slider_block
}
/**
* 鼠標按下事件處理
*/
function mousedownHandler(event){
//計算鼠標相對滑動塊的左邊距,進而在鼠標移動事件處理函數(shù)中使用
//鼠標相對滑動塊左邊距=鼠標相對視口左邊距-滑動塊相對視口左邊距
slider_instance.mouseLeft=event.clientX-getPageLeft(this);
console.log(getPageLeft(this));
slider_instance.outer.addEventListener("mousemove",mousemoveHandler,false);
}
/**
* 鼠標移動事件處理
*/
function mousemoveHandler(event){
//計算出應(yīng)當設(shè)置的滑動塊左邊距(相對于父容器)
//滑動塊相對于滑動條左邊距=鼠標相對于視口左邊距-滑動條相對于視口左邊距-鼠標相對于滑動塊左邊距
var blockLeft=event.clientX-slider_instance.slider_bar_pageLeft-slider_instance.mouseLeft;
//如若滑動塊相對于父容器左邊距大于滑動塊可移動寬度或小于0,表示過界;設(shè)置為左右界限值
if(blockLeft>slider_instance.slider_bar_width){
blockLeft=slider_instance.slider_bar_width
}else if(blockLeft<0){
blockLeft=0;
}
//設(shè)置滑動塊的新位置
slider_instance.slider_block.style.left=blockLeft+"px";
//按照滾動塊已滾動的百分比,設(shè)置被滾動元素的marginLeft(負值),進而讓其滾動起來
//被滾動元素的左margin=-(滑動塊相對于滑動條左邊距/可滑動最大寬度*可滾動元素的最大寬度)
slider_instance.slider_content.style.marginLeft="-"+(blockLeft/slider_instance.slider_bar_width*slider_instance.slider_content_width)+"px";
}
/**
* 鼠標鍵彈起事件處理
*/
function mouseupHandler(event){
slider_instance.outer.removeEventListener("mousemove",mousemoveHandler,false);
}
/**
* 獲得元素的視口左邊距
*/
function getPageLeft(el){
var result=el.offsetLeft;
var parent=el.offsetParent;
while(parent!==null){
result+=parent.offsetLeft;
parent=parent.offsetParent;
}
return result;
}
}
//用test_div元素進行展示
new Slider(document.getElementsByClassName("test_div")[0]);
}
</script>
<body>
<div class="outer">
<div class="test_div"></div>
</div>
</body>
</html>
希望本文所述對大家學(xué)習javascript程序設(shè)計有所幫助。
相關(guān)文章
JavaScript中遍歷跳出循環(huán)方法總結(jié)
這篇文章主要給大家介紹了關(guān)于JavaScript中遍歷跳出循環(huán)方法的相關(guān)資料,一想到想到循環(huán)的跳出,立馬就會想到三個關(guān)鍵,break、return、continue,在業(yè)務(wù)中也會需要在遍歷的時候退出循環(huán),需要的朋友可以參考下2023-12-12
小議Function.apply()之二------利用Apply的參數(shù)數(shù)組化來提高 JavaScript程序性能
小議Function.apply()之二------利用Apply的參數(shù)數(shù)組化來提高 JavaScript程序性能...2006-11-11
基于JS實現(xiàn)9種不同的面包屑和分布式多步驟導(dǎo)航效果
本文是小編給大家分享的基于js實現(xiàn)的9種不同風格的面包屑和分布式多步驟導(dǎo)航效果,非常不錯,具有參考借鑒價值,需要的朋友參考下2017-02-02
layui 實現(xiàn)二級彈窗彈出之后 關(guān)閉一級彈窗的方法
今天小編就為大家分享一篇layui 實現(xiàn)二級彈窗彈出之后 關(guān)閉一級彈窗的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09

