[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /*----------------------------------------------------------------------------\ 2 | Slider 1.02 | 3 |-----------------------------------------------------------------------------| 4 | Created by Erik Arvidsson | 5 | (http://webfx.eae.net/contact.html#erik) | 6 | For WebFX (http://webfx.eae.net/) | 7 |-----------------------------------------------------------------------------| 8 | A slider control that degrades to an input control for non supported | 9 | browsers. | 10 |-----------------------------------------------------------------------------| 11 | Copyright (c) 2002, 2003, 2006 Erik Arvidsson | 12 |-----------------------------------------------------------------------------| 13 | Licensed under the Apache License, Version 2.0 (the "License"); you may not | 14 | use this file except in compliance with the License. You may obtain a copy | 15 | of the License at http://www.apache.org/licenses/LICENSE-2.0 | 16 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 17 | Unless required by applicable law or agreed to in writing, software | 18 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 19 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | 20 | License for the specific language governing permissions and limitations | 21 | under the License. | 22 |-----------------------------------------------------------------------------| 23 | Dependencies: timer.js - an OO abstraction of timers | 24 | range.js - provides the data model for the slider | 25 | winclassic.css or any other css file describing the look | 26 |-----------------------------------------------------------------------------| 27 | 2002-10-14 | Original version released | 28 | 2003-03-27 | Added a test in the constructor for missing oElement arg | 29 | 2003-11-27 | Only use mousewheel when focused | 30 | 2006-05-28 | Changed license to Apache Software License 2.0. | 31 |-----------------------------------------------------------------------------| 32 | Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 | 33 \----------------------------------------------------------------------------*/ 34 35 Slider.isSupported = typeof document.createElement != "undefined" && 36 typeof document.documentElement != "undefined" && 37 typeof document.documentElement.offsetWidth == "number"; 38 39 40 function Slider(oElement, oInput, sOrientation) { 41 if (!oElement) return; 42 this._orientation = sOrientation || "horizontal"; 43 this._range = new Range(); 44 this._range.setExtent(0); 45 this._blockIncrement = 10; 46 this._unitIncrement = 1; 47 this._timer = new Timer(100); 48 49 50 if (Slider.isSupported && oElement) { 51 52 this.document = oElement.ownerDocument || oElement.document; 53 54 this.element = oElement; 55 this.element.slider = this; 56 this.element.unselectable = "on"; 57 58 // add class name tag to class name 59 this.element.className = this._orientation + " " + this.classNameTag + " " + this.element.className; 60 61 // create line 62 this.line = this.document.createElement("DIV"); 63 this.line.className = "line"; 64 this.line.unselectable = "on"; 65 this.line.appendChild(this.document.createElement("DIV")); 66 this.element.appendChild(this.line); 67 68 // create handle 69 this.handle = this.document.createElement("DIV"); 70 this.handle.className = "handle"; 71 this.handle.unselectable = "on"; 72 this.handle.appendChild(this.document.createElement("DIV")); 73 this.handle.firstChild.appendChild( 74 this.document.createTextNode(String.fromCharCode(160))); 75 this.element.appendChild(this.handle); 76 } 77 78 this.input = oInput; 79 80 // events 81 var oThis = this; 82 this._range.onchange = function () { 83 oThis.recalculate(); 84 if (typeof oThis.onchange == "function") 85 oThis.onchange(); 86 }; 87 88 if (Slider.isSupported && oElement) { 89 this.element.onfocus = Slider.eventHandlers.onfocus; 90 this.element.onblur = Slider.eventHandlers.onblur; 91 this.element.onmousedown = Slider.eventHandlers.onmousedown; 92 this.element.onmouseover = Slider.eventHandlers.onmouseover; 93 this.element.onmouseout = Slider.eventHandlers.onmouseout; 94 this.element.onkeydown = Slider.eventHandlers.onkeydown; 95 this.element.onkeypress = Slider.eventHandlers.onkeypress; 96 this.element.onmousewheel = Slider.eventHandlers.onmousewheel; 97 this.handle.onselectstart = 98 this.element.onselectstart = function () { return false; }; 99 100 this._timer.ontimer = function () { 101 oThis.ontimer(); 102 }; 103 104 // extra recalculate for ie 105 window.setTimeout(function() { 106 oThis.recalculate(); 107 }, 1); 108 } 109 else { 110 this.input.onchange = function (e) { 111 oThis.setValue(oThis.input.value); 112 }; 113 } 114 } 115 116 Slider.eventHandlers = { 117 118 // helpers to make events a bit easier 119 getEvent: function (e, el) { 120 if (!e) { 121 if (el) 122 e = el.document.parentWindow.event; 123 else 124 e = window.event; 125 } 126 if (!e.srcElement) { 127 var el = e.target; 128 while (el != null && el.nodeType != 1) 129 el = el.parentNode; 130 e.srcElement = el; 131 } 132 if (typeof e.offsetX == "undefined") { 133 e.offsetX = e.layerX; 134 e.offsetY = e.layerY; 135 } 136 137 return e; 138 }, 139 140 getDocument: function (e) { 141 if (e.target) 142 return e.target.ownerDocument; 143 return e.srcElement.document; 144 }, 145 146 getSlider: function (e) { 147 var el = e.target || e.srcElement; 148 while (el != null && el.slider == null) { 149 el = el.parentNode; 150 } 151 if (el) 152 return el.slider; 153 return null; 154 }, 155 156 getLine: function (e) { 157 var el = e.target || e.srcElement; 158 while (el != null && el.className != "line") { 159 el = el.parentNode; 160 } 161 return el; 162 }, 163 164 getHandle: function (e) { 165 var el = e.target || e.srcElement; 166 var re = /handle/; 167 while (el != null && !re.test(el.className)) { 168 el = el.parentNode; 169 } 170 return el; 171 }, 172 // end helpers 173 174 onfocus: function (e) { 175 var s = this.slider; 176 s._focused = true; 177 s.handle.className = "handle hover"; 178 }, 179 180 onblur: function (e) { 181 var s = this.slider 182 s._focused = false; 183 s.handle.className = "handle"; 184 }, 185 186 onmouseover: function (e) { 187 e = Slider.eventHandlers.getEvent(e, this); 188 var s = this.slider; 189 if (e.srcElement == s.handle) 190 s.handle.className = "handle hover"; 191 }, 192 193 onmouseout: function (e) { 194 e = Slider.eventHandlers.getEvent(e, this); 195 var s = this.slider; 196 if (e.srcElement == s.handle && !s._focused) 197 s.handle.className = "handle"; 198 }, 199 200 onmousedown: function (e) { 201 e = Slider.eventHandlers.getEvent(e, this); 202 var s = this.slider; 203 if (s.element.focus) 204 s.element.focus(); 205 206 Slider._currentInstance = s; 207 var doc = s.document; 208 209 if (doc.addEventListener) { 210 doc.addEventListener("mousemove", Slider.eventHandlers.onmousemove, true); 211 doc.addEventListener("mouseup", Slider.eventHandlers.onmouseup, true); 212 } 213 else if (doc.attachEvent) { 214 doc.attachEvent("onmousemove", Slider.eventHandlers.onmousemove); 215 doc.attachEvent("onmouseup", Slider.eventHandlers.onmouseup); 216 doc.attachEvent("onlosecapture", Slider.eventHandlers.onmouseup); 217 s.element.setCapture(); 218 } 219 220 if (Slider.eventHandlers.getHandle(e)) { // start drag 221 Slider._sliderDragData = { 222 screenX: e.screenX, 223 screenY: e.screenY, 224 dx: e.screenX - s.handle.offsetLeft, 225 dy: e.screenY - s.handle.offsetTop, 226 startValue: s.getValue(), 227 slider: s 228 }; 229 } 230 else { 231 var lineEl = Slider.eventHandlers.getLine(e); 232 s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0); 233 s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0); 234 s._increasing = null; 235 s.ontimer(); 236 } 237 }, 238 239 onmousemove: function (e) { 240 e = Slider.eventHandlers.getEvent(e, this); 241 242 if (Slider._sliderDragData) { // drag 243 var s = Slider._sliderDragData.slider; 244 245 var boundSize = s.getMaximum() - s.getMinimum(); 246 var size, pos, reset; 247 248 if (s._orientation == "horizontal") { 249 size = s.element.offsetWidth - s.handle.offsetWidth; 250 pos = e.screenX - Slider._sliderDragData.dx; 251 reset = Math.abs(e.screenY - Slider._sliderDragData.screenY) > 100; 252 } 253 else { 254 size = s.element.offsetHeight - s.handle.offsetHeight; 255 pos = s.element.offsetHeight - s.handle.offsetHeight - 256 (e.screenY - Slider._sliderDragData.dy); 257 reset = Math.abs(e.screenX - Slider._sliderDragData.screenX) > 100; 258 } 259 s.setValue(reset ? Slider._sliderDragData.startValue : 260 s.getMinimum() + boundSize * pos / size); 261 return false; 262 } 263 else { 264 var s = Slider._currentInstance; 265 if (s != null) { 266 var lineEl = Slider.eventHandlers.getLine(e); 267 s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0); 268 s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0); 269 } 270 } 271 272 }, 273 274 onmouseup: function (e) { 275 e = Slider.eventHandlers.getEvent(e, this); 276 var s = Slider._currentInstance; 277 var doc = s.document; 278 if (doc.removeEventListener) { 279 doc.removeEventListener("mousemove", Slider.eventHandlers.onmousemove, true); 280 doc.removeEventListener("mouseup", Slider.eventHandlers.onmouseup, true); 281 } 282 else if (doc.detachEvent) { 283 doc.detachEvent("onmousemove", Slider.eventHandlers.onmousemove); 284 doc.detachEvent("onmouseup", Slider.eventHandlers.onmouseup); 285 doc.detachEvent("onlosecapture", Slider.eventHandlers.onmouseup); 286 s.element.releaseCapture(); 287 } 288 289 if (Slider._sliderDragData) { // end drag 290 Slider._sliderDragData = null; 291 } 292 else { 293 s._timer.stop(); 294 s._increasing = null; 295 } 296 Slider._currentInstance = null; 297 }, 298 299 onkeydown: function (e) { 300 e = Slider.eventHandlers.getEvent(e, this); 301 //var s = Slider.eventHandlers.getSlider(e); 302 var s = this.slider; 303 var kc = e.keyCode; 304 switch (kc) { 305 case 33: // page up 306 s.setValue(s.getValue() + s.getBlockIncrement()); 307 break; 308 case 34: // page down 309 s.setValue(s.getValue() - s.getBlockIncrement()); 310 break; 311 case 35: // end 312 s.setValue(s.getOrientation() == "horizontal" ? 313 s.getMaximum() : 314 s.getMinimum()); 315 break; 316 case 36: // home 317 s.setValue(s.getOrientation() == "horizontal" ? 318 s.getMinimum() : 319 s.getMaximum()); 320 break; 321 case 38: // up 322 case 39: // right 323 s.setValue(s.getValue() + s.getUnitIncrement()); 324 break; 325 326 case 37: // left 327 case 40: // down 328 s.setValue(s.getValue() - s.getUnitIncrement()); 329 break; 330 } 331 332 if (kc >= 33 && kc <= 40) { 333 return false; 334 } 335 }, 336 337 onkeypress: function (e) { 338 e = Slider.eventHandlers.getEvent(e, this); 339 var kc = e.keyCode; 340 if (kc >= 33 && kc <= 40) { 341 return false; 342 } 343 }, 344 345 onmousewheel: function (e) { 346 e = Slider.eventHandlers.getEvent(e, this); 347 var s = this.slider; 348 if (s._focused) { 349 s.setValue(s.getValue() + e.wheelDelta / 120 * s.getUnitIncrement()); 350 // windows inverts this on horizontal sliders. That does not 351 // make sense to me 352 return false; 353 } 354 } 355 }; 356 357 358 359 Slider.prototype.classNameTag = "dynamic-slider-control", 360 361 Slider.prototype.setValue = function (v) { 362 this._range.setValue(v); 363 this.input.value = this.getValue(); 364 }; 365 366 Slider.prototype.getValue = function () { 367 return this._range.getValue(); 368 }; 369 370 Slider.prototype.setMinimum = function (v) { 371 this._range.setMinimum(v); 372 this.input.value = this.getValue(); 373 }; 374 375 Slider.prototype.getMinimum = function () { 376 return this._range.getMinimum(); 377 }; 378 379 Slider.prototype.setMaximum = function (v) { 380 this._range.setMaximum(v); 381 this.input.value = this.getValue(); 382 }; 383 384 Slider.prototype.getMaximum = function () { 385 return this._range.getMaximum(); 386 }; 387 388 Slider.prototype.setUnitIncrement = function (v) { 389 this._unitIncrement = v; 390 }; 391 392 Slider.prototype.getUnitIncrement = function () { 393 return this._unitIncrement; 394 }; 395 396 Slider.prototype.setBlockIncrement = function (v) { 397 this._blockIncrement = v; 398 }; 399 400 Slider.prototype.getBlockIncrement = function () { 401 return this._blockIncrement; 402 }; 403 404 Slider.prototype.getOrientation = function () { 405 return this._orientation; 406 }; 407 408 Slider.prototype.setOrientation = function (sOrientation) { 409 if (sOrientation != this._orientation) { 410 if (Slider.isSupported && this.element) { 411 // add class name tag to class name 412 this.element.className = this.element.className.replace(this._orientation, 413 sOrientation); 414 } 415 this._orientation = sOrientation; 416 this.recalculate(); 417 418 } 419 }; 420 421 Slider.prototype.recalculate = function() { 422 if (!Slider.isSupported || !this.element) return; 423 424 var w = this.element.offsetWidth; 425 var h = this.element.offsetHeight; 426 var hw = this.handle.offsetWidth; 427 var hh = this.handle.offsetHeight; 428 var lw = this.line.offsetWidth; 429 var lh = this.line.offsetHeight; 430 431 // this assumes a border-box layout 432 433 if (this._orientation == "horizontal") { 434 this.handle.style.left = (w - hw) * (this.getValue() - this.getMinimum()) / 435 (this.getMaximum() - this.getMinimum()) + "px"; 436 this.handle.style.top = (h - hh) / 2 + "px"; 437 438 this.line.style.top = (h - lh) / 2 + "px"; 439 this.line.style.left = hw / 2 + "px"; 440 //this.line.style.right = hw / 2 + "px"; 441 this.line.style.width = Math.max(0, w - hw - 2)+ "px"; 442 this.line.firstChild.style.width = Math.max(0, w - hw - 4)+ "px"; 443 } 444 else { 445 this.handle.style.left = (w - hw) / 2 + "px"; 446 this.handle.style.top = h - hh - (h - hh) * (this.getValue() - this.getMinimum()) / 447 (this.getMaximum() - this.getMinimum()) + "px"; 448 449 this.line.style.left = (w - lw) / 2 + "px"; 450 this.line.style.top = hh / 2 + "px"; 451 this.line.style.height = Math.max(0, h - hh - 2) + "px"; //hard coded border width 452 //this.line.style.bottom = hh / 2 + "px"; 453 this.line.firstChild.style.height = Math.max(0, h - hh - 4) + "px"; //hard coded border width 454 } 455 }; 456 457 Slider.prototype.ontimer = function () { 458 var hw = this.handle.offsetWidth; 459 var hh = this.handle.offsetHeight; 460 var hl = this.handle.offsetLeft; 461 var ht = this.handle.offsetTop; 462 463 if (this._orientation == "horizontal") { 464 if (this._mouseX > hl + hw && 465 (this._increasing == null || this._increasing)) { 466 this.setValue(this.getValue() + this.getBlockIncrement()); 467 this._increasing = true; 468 } 469 else if (this._mouseX < hl && 470 (this._increasing == null || !this._increasing)) { 471 this.setValue(this.getValue() - this.getBlockIncrement()); 472 this._increasing = false; 473 } 474 } 475 else { 476 if (this._mouseY > ht + hh && 477 (this._increasing == null || !this._increasing)) { 478 this.setValue(this.getValue() - this.getBlockIncrement()); 479 this._increasing = false; 480 } 481 else if (this._mouseY < ht && 482 (this._increasing == null || this._increasing)) { 483 this.setValue(this.getValue() + this.getBlockIncrement()); 484 this._increasing = true; 485 } 486 } 487 488 this._timer.start(); 489 };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 17 22:47:18 2015 | Cross-referenced by PHPXref 0.7.1 |