修正了获取元素相对视口左距离的逻辑问题(之前的函数实际获取的是相对于页面左距离)。去除了调试时忘记删除的mouseleave事件。将创建滚动条的功能单独列为一个函数。
添加了鼠标点在滚动条什么位置,就立即卷动到什么位置的功能;添加了键盘左右键滚动的功能(滚动距离为一个内容页面)
<!DOCTYPE html>
<html>
<head>
<title>A demo</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(){
function Slider(slider_content){
var slider_instance=this;
this.slider_content=slider_content;
this.outer=slider_content.parentNode; createSlider(); 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("mouseup",mouseupHandler,false);
this.slider_bar.addEventListener("click",sliderbarClickHandler,false);
this.outer.addEventListener("keydown",sliderbarKeydownHandler,false); function createSlider(){
slider_instance.slider_bar=document.createElement("div");
slider_instance.slider_bar.className="slider_bar";
slider_instance.slider_block=document.createElement("div");
slider_instance.slider_block.className="slider_block";
slider_instance.slider_bar.appendChild(slider_instance.slider_block);
slider_instance.outer.appendChild(slider_instance.slider_bar);
}
function mousedownHandler(event){
slider_instance.mouseLeft=event.clientX-getPageLeft(this);
slider_instance.outer.addEventListener("mousemove",mousemoveHandler,false);
}
function mousemoveHandler(event){
var blockLeft=event.clientX-slider_instance.slider_bar_pageLeft-slider_instance.mouseLeft;
if(blockLeft>slider_instance.slider_bar_width){
blockLeft=slider_instance.slider_bar_width
}else if(blockLeft<0){
blockLeft=0;
}
slider_instance.slider_block.style.left=blockLeft+"px";
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 sliderbarClickHandler(event){
if(event.target!=slider_instance.slider_block){
var blockLeft=event.clientX-slider_instance.slider_bar_pageLeft-slider_instance.slider_block.offsetWidth/2;
if(blockLeft>slider_instance.slider_bar_width){
blockLeft=slider_instance.slider_bar_width
}else if(blockLeft<0){
blockLeft=0;
}
slider_instance.slider_block.style.left=blockLeft+"px";
slider_instance.slider_content.style.marginLeft="-"+(blockLeft/slider_instance.slider_bar_width*slider_instance.slider_content_width)+"px";;
}
}
function sliderbarKeydownHandler(event){
var newMarginLeft,scrollPercent;
switch(event.keyCode){
//left
case 39:{
if(parseInt(slider_instance.slider_content.style.marginLeft)!=slider_instance.slider_content_width){
newMarginLeft=parseInt(slider_instance.slider_content.style.marginLeft)-slider_instance.outer.clientWidth;
if(-newMarginLeft>slider_instance.slider_content_width){
newMarginLeft=-slider_instance.slider_content_width;
}
scrollPercent=-newMarginLeft/slider_instance.slider_content_width;
slider_instance.slider_content.style.marginLeft=newMarginLeft+"px";
slider_instance.slider_block.style.left=scrollPercent*slider_instance.slider_bar_width+"px";
}
break;
}
case 37:{
if(parseInt(slider_instance.slider_content.style.marginLeft)!=0){
newMarginLeft=parseInt(slider_instance.slider_content.style.marginLeft)+slider_instance.outer.clientWidth;
if(newMarginLeft>0){
newMarginLeft=0;
}
scrollPercent=-newMarginLeft/slider_instance.slider_content_width;
slider_instance.slider_content.style.marginLeft=newMarginLeft+"px";
slider_instance.slider_block.style.left=scrollPercent*slider_instance.slider_bar_width+"px";
}
break;
}
}
}
function getPageLeft(el){
return el.getBoundingClientRect().left;
}
}
new Slider(document.getElementsByClassName("test_div")[0]); }
</script>
<body>
<div class="outer" tabindex="1">
<div class="test_div"></div>
</div>
</body>
</html>