又一个简单试用的javascript Slider插件
运行效果:
页面代码
<!DOCTYPE html > <html > <head> <title>JavaScript Slider (sample)</title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <link rel="stylesheet" type="text/css" href="slider.css" /> <script src="jquery-1.8.2.js" type="text/javascript"></script> <script type="text/javascript" src="slider.js"></script> <script type="text/javascript"> window.onload = function () { new Slider('my-slider', { value: 0.2, snapping:false, callback: function (value) { $(".handle").attr("title",(Number(value)*1500).toFixed(0)+"米"); } }); } </script> </head> <body> <div id="my-slider" class="slider"> <div class="handle" title="300米"></div> </div> </body> </html>
slider.js
View Code
/** * JavaScript Slider v0.9 * http://blog.ovidiu.ch/javascript-slider * * Copyright (c) 2010, Ovidiu Cherecheș * MIT License * http://legal.ovidiu.ch/licenses/MIT */ /* Mouse */ var Mouse = { x: 0, y: 0, refresh: function(e) { var posx = 0, posy = 0; if(!e) { e = window.event; } if(e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else if(e.clientX || e.clientY) { posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } this.x = posx; this.y = posy; } }; var mouseMoveHandler = document.onmousemove || function(){}; document.onmousemove = function(e) { mouseMoveHandler(e); Mouse.refresh(e); } /* Position */ var Position = { get: function(obj) { var curleft = curtop = 0; if(obj.offsetParent) { do { curleft += obj.offsetLeft; curtop += obj.offsetTop; } while((obj = obj.offsetParent)); } return [curleft, curtop]; } }; /* Slider */ var Slider = function(wrapper, options) { if(typeof(wrapper) == 'string') { wrapper = document.getElementById(wrapper); } if(!wrapper) { return; } var handle = wrapper.getElementsByTagName('div')[0]; if(!handle || handle.className.search(/(^|\s)handle(\s|$)/) == -1) { return; } this.init(wrapper, handle, options || {}); this.setup(); }; Slider.prototype = { init: function(wrapper, handle, options) { this.wrapper = wrapper; this.handle = handle; this.options = options; this.value = { current: options.value || 0, target: options.value || 0, prev: -1 }; this.disabled = options.disabled || false; this.steps = options.steps || 0; this.snapping = options.snapping || false; this.speed = options.speed || 5; this.callback = options.callback || null; this.animation_callback = options.animation_callback || null; this.bounds = { pleft: options.pleft || 0, left: 0, pright: -(options.pright || 0), right: 0, width: 0, diff: 0 }; this.offset = { wrapper: 0, mouse: 0, target: 0, current: 0, prev: -9999 }; this.dragging = false; this.tapping = false; }, setup: function() { var self = this; this.wrapper.onselectstart = function() { return false; } this.handle.onmousedown = function(e) { self.preventDefaults(e, true); this.focus(); self.handleMouseDownHandler(e); }; this.wrapper.onmousedown = function(e) { self.preventDefaults(e); self.wrapperMouseDownHandler(e); }; var mouseUpHandler = document.onmouseup || function(){}; document.onmouseup = function(e) { mouseUpHandler(e); self.preventDefaults(e); self.documentMouseUpHandler(e); }; var resizeHandler = document.onresize || function(){}; window.onresize = function(e) { resizeHandler(e); self.setWrapperOffset(); self.setBounds(); }; this.setWrapperOffset(); if(!this.bounds.pleft && !this.bounds.pright) { this.bounds.pleft = Position.get(this.handle)[0] - this.offset.wrapper; this.bounds.pright = -this.bounds.pleft; } this.setBounds(); this.setSteps(); this.interval = setInterval(function(){ self.animate() }, 20); self.animate(false, true); }, setWrapperOffset: function() { this.offset.wrapper = Position.get(this.wrapper)[0]; }, setBounds: function() { this.bounds.left = this.bounds.pleft; this.bounds.right = this.bounds.pright + this.wrapper.offsetWidth; this.bounds.width = this.bounds.right - this.bounds.left; this.bounds.diff = this.bounds.width - this.handle.offsetWidth; }, setSteps: function() { if(this.steps > 1) { this.stepsRatio = []; for(var i = 0; i <= this.steps - 1; i++) { this.stepsRatio[i] = i / (this.steps - 1); } } }, disable: function() { this.disabled = true; this.handle.className += ' disabled'; }, enable: function() { this.disabled = false; this.handle.className = this.handle.className.replace(/\s?disabled/g, ''); }, handleMouseDownHandler: function(e) { this.startDrag(); this.cancelEvent(e); }, wrapperMouseDownHandler: function(e) { this.startTap(); }, documentMouseUpHandler: function(e) { this.stopDrag(); this.stopTap(); }, startTap: function(target) { if(this.disabled) { return; } if(target === undefined) { target = Mouse.x - this.offset.wrapper - (this.handle.offsetWidth / 2); } this.setOffsetTarget(target); this.tapping = true; }, stopTap: function() { if(this.disabled || !this.tapping) { return; } this.setOffsetTarget(this.offset.current); this.tapping = false; this.result(); }, startDrag: function() { if(this.disabled) { return; } this.offset.mouse = Mouse.x - Position.get(this.handle)[0]; this.dragging = true; }, stopDrag: function() { if(this.disabled || !this.dragging) { return; } this.dragging = false; this.result(); }, feedback: function() { var value = this.value.current; if(this.steps > 1 && this.snapping) { value = this.getClosestStep(value); } if(value != this.value.prev) { if(typeof(this.animation_callback) == 'function') { this.animation_callback(value); } this.value.prev = value; } }, result: function() { var value = this.value.target; if(this.steps > 1) { value = this.getClosestStep(value); } if(typeof(this.callback) == 'function') { this.callback(value); } }, animate: function(onMove, first) { if(onMove && !this.dragging) { return; } if(this.dragging) { this.setOffsetTarget(Mouse.x - this.offset.mouse - this.offset.wrapper); } this.value.target = Math.max(this.value.target, 0); this.value.target = Math.min(this.value.target, 1); this.offset.target = this.getOffsetByRatio(this.value.target); if((!this.dragging && !this.tapping) || this.snapping) { if(this.steps > 1) { this.setValueTarget(this.getClosestStep(this.value.target)); } } if(this.dragging || first) { this.value.current = this.value.target; } this.slide(); this.show(); this.feedback(); }, slide: function() { if(this.value.target > this.value.current) { this.value.current += Math.min(this.value.target - this.value.current, this.speed / 100); } else if(this.value.target < this.value.current) { this.value.current -= Math.min(this.value.current - this.value.target, this.speed / 100); } if(!this.snapping) { this.offset.current = this.getOffsetByRatio(this.value.current); } else { this.offset.current = this.getOffsetByRatio( this.getClosestStep(this.value.current) ); } }, show: function() { if(this.offset.current != this.offset.prev) { this.handle.style.left = String(this.offset.current) + 'px'; this.offset.prev = this.offset.current; } }, setValue: function(value, snap) { this.setValueTarget(value); if(snap) { this.value.current = this.value.target; } }, setValueTarget: function(value) { this.value.target = value; this.offset.target = this.getOffsetByRatio(value); }, setOffsetTarget: function(value) { this.offset.target = value; this.value.target = this.getRatioByOffset(value); }, getRatioByOffset: function(offset) { return (offset - this.bounds.left) / this.bounds.diff; }, getOffsetByRatio: function(ratio) { return Math.round(ratio * this.bounds.diff) + this.bounds.left; }, getClosestStep: function(value) { var k = 0; var min = 1; for(var i = 0; i <= this.steps - 1; i++) { if(Math.abs(this.stepsRatio[i] - value) < min) { min = Math.abs(this.stepsRatio[i] - value); k = i; } } return this.stepsRatio[k]; }, preventDefaults: function(e, selection) { if(!e) { e = window.event; } if(e.preventDefault) { e.preventDefault(); } if(selection && document.selection) { document.selection.empty(); } }, cancelEvent: function(e) { if(!e) { e = window.event; } if(e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; } } };
slider.css
View Code
.slider { width: 600px; height: 20px; font-family: Helvetica, Arial, sans-serif; font-size: 12px; position: relative; background: #EEE; -moz-border-radius: 3px; -webkit-border-radius: 3px; } .slider .handle { position: absolute; width: 30px; height: 20px; background: #4CB848; color: lightblue; line-height: 30px; text-align: center; cursor: pointer; -moz-border-radius: 3px; -webkit-border-radius: 3px; } .slider .disabled { background: #898989; }
参考
* http://blog.ovidiu.ch/javascript-slider
* http://legal.ovidiu.ch/licenses/MIT