最近公司在做一個項目,頁面中要用到滑動器效果,我的第一反應是使用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 { /*width: 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都退役了。