最近公司在做一个项目,页面中要用到滑动器效果,我的第一反应是使用HTML5 input类型中的range类型,但马上我就否定了这个想法,因为range类型存在浏览器的兼容性问题(在主流浏览器中)。但又不想在网上随便抄别人写的,于是就自己动手写了一个滑动器。
先贴上效果图:
滑动器的HTML代码如下:
<div class="ui-slide"> <input type="text" value="0" /> <div class="slider-track"> <span class="min">0</span><span class="slider-thumb"></span><span class="max">1000</span> </div> </div>
其实只要下面的代码就够了:
<div class="ui-slide"> <div class="slider-track"> <span class="slider-thumb"></span> </div> </div>
但是为了滑动效果看起来更形象,还加了一个输入框(用来动态显示滑动条的值)、还有最大值、最小值。
滑动器css代码如下:
<style> .ui-slide { width: 400px; margin: 0 auto; /*margin-left: 100px;*/ text-align: center; } .slider-track { /* 50%;*/ height: 15px; border-radius: 1em; border: 1px solid #AAAAAA; background: linear-gradient(#E5E5E5, #F2F2F2) repeat scroll 0 0 #EEEEEE; position: relative; } .slider-thumb { display: block; width: 28px; height: 28px; border: 1px solid grey; border-radius: 1em; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); background: linear-gradient(#FAFAFA, #F6F6F6) repeat scroll 0 0 #FFFFFF; position: absolute; /*left: 0;*/ top: 50%; margin: -15px 0 0 -15px; } input[type="text"] { display: inline-block; margin-bottom: 1em; width: 3em; text-align: center; } .min, .max { position: absolute; } .min { left: -30px; } .max { right: -60px; } </style>
上面的代码已经有滑动条的样子了,只是不能滑动。下面用js来控制滑动,先上代码:
<script> var sliderThumb = document.getElementsByClassName("slider-thumb")[0];
var input = document.getElementsByTagName("input")[0]; sliderThumb.style.left = "0px"; sliderThumb.onmousedown = function (evt) { var that = this; var oldX = evt.clientX; var left = parseInt(that.style.left); sliderThumb.onmousemove = function(evt) { var x = evt.clientX - oldX; that.style.left = left + x + "px"; if ( parseInt(that.style.left) < 0) { that.style.left = 0; } if (parseInt(that.style.left) > 400) { that.style.left = 400 + "px"; } }
input .value = Math.ceil(parseInt(that.style.left) / 400 * 1000); sliderThumb.onmouseup = function (evt) { sliderThumb.onmouseup = null; sliderThumb.onmousemove = null; } } </script>
由于style特性获取不到外部样式表或嵌入样式表的样式,所以需要用js设置sliderThumb.style.left="0px",否则后面获取
sliderThumb.style.left
的值都为空。
到这边其实滑动效果已经有了,但是有些问题,当鼠标移动的太快,就会出现鼠标脱离滑块,因为mouseover事件是绑定到滑块上的,一旦鼠标脱离滑块,就无法再调用mousemove事件,无法调用mousemove事件,就无法定位滑块的位置,所以滑块就停止了。还有一个问题是,当你拖动滑块快速的移动鼠标,然后放开,再把鼠标悬浮在滑块上时,你会发现,鼠标悬浮在滑块上也能拖动滑块,原因是快速移动鼠标后,鼠标脱离滑块,当鼠标up时,本来mouseup是绑定在滑块上的,应该执行下面这个函数的来取消事件绑定:
sliderThumb.onmouseup = function (evt) { sliderThumb.onmouseup = null; sliderThumb.onmousemove = null; }
但现在鼠标已经脱离滑块,mouseup时并不会执行上面的函数,所以滑块的mouseup并没有执行,这样就出现鼠标悬浮在滑块上时也能拖动滑块。
现在我们来解决上面出现的两个问题,把上面的js代码改成这样:
<script> var sliderThumb = document.getElementsByClassName("slider-thumb")[0]; var input = document.getElementsByTagName("input")[0]; sliderThumb.style.left = "0px"; sliderThumb.onmousedown = function (evt) { var that = this; var oldX = evt.clientX; var left = parseInt(that.style.left); document.onmousemove = function(evt) { var x = evt.clientX - oldX; that.style.left = left + x + "px"; if ( parseInt(that.style.left) < 0) { that.style.left = 0; } if (parseInt(that.style.left) > 400) { that.style.left = 400 + "px"; } } input.value = Math.ceil(parseInt(that.style.left) / 400 * 1000); document.onmouseup = function (evt) { document.onmouseup = null; document.onmousemove = null; } } </script>
大家会发现,我把mousemove与mouseup事件都绑定到了document上,但mousedown事件还是绑定在滑块上。这样一来,即使鼠标移动太快脱离滑块,滑块也能移动,因为document上的mousemove事件只要鼠标还没松开就会执行。当mouseup时会执行这个函数:
document.onmouseup = function (evt) { document.onmouseup = null; document.onmousemove = null; }
这样就取消了事件,就不会出现放开鼠标还能悬浮移动滑块的情况了。
下面就是滑块的效果了,请拖动下面的滑块滑动:
这篇文章并没有考虑低版本的IE浏览器(ie9以下),毕竟windows XP都退役了。