github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/js/slider/bootstrap-slider.js (about) 1 /* ========================================================= 2 * bootstrap-slider.js v2.0.0 3 * http://www.eyecon.ro/bootstrap-slider 4 * ========================================================= 5 * Copyright 2012 Stefan Petre 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * ========================================================= */ 19 20 !function( $ ) { 21 22 var Slider = function(element, options) { 23 this.element = $(element); 24 this.picker = $('<div class="slider">'+ 25 '<div class="slider-track">'+ 26 '<div class="slider-selection"></div>'+ 27 '<div class="slider-handle"></div>'+ 28 '<div class="slider-handle"></div>'+ 29 '</div>'+ 30 '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'+ 31 '</div>') 32 .insertBefore(this.element) 33 .append(this.element); 34 this.id = this.element.data('slider-id')||options.id; 35 if (this.id) { 36 this.picker[0].id = this.id; 37 } 38 39 if (typeof Modernizr !== 'undefined' && Modernizr.touch) { 40 this.touchCapable = true; 41 } 42 43 var tooltip = this.element.data('slider-tooltip')||options.tooltip; 44 45 this.tooltip = this.picker.find('.tooltip'); 46 this.tooltipInner = this.tooltip.find('div.tooltip-inner'); 47 48 this.orientation = this.element.data('slider-orientation')||options.orientation; 49 switch(this.orientation) { 50 case 'vertical': 51 this.picker.addClass('slider-vertical'); 52 this.stylePos = 'top'; 53 this.mousePos = 'pageY'; 54 this.sizePos = 'offsetHeight'; 55 this.tooltip.addClass('right')[0].style.left = '100%'; 56 break; 57 default: 58 this.picker 59 .addClass('slider-horizontal') 60 .css('width', this.element.outerWidth()); 61 this.orientation = 'horizontal'; 62 this.stylePos = 'left'; 63 this.mousePos = 'pageX'; 64 this.sizePos = 'offsetWidth'; 65 this.tooltip.addClass('top')[0].style.top = -this.tooltip.outerHeight() - 14 + 'px'; 66 break; 67 } 68 69 this.min = this.element.data('slider-min')||options.min; 70 this.max = this.element.data('slider-max')||options.max; 71 this.step = this.element.data('slider-step')||options.step; 72 this.value = this.element.data('slider-value')||options.value; 73 if (this.value[1]) { 74 this.range = true; 75 } 76 77 this.selection = this.element.data('slider-selection')||options.selection; 78 this.selectionEl = this.picker.find('.slider-selection'); 79 if (this.selection === 'none') { 80 this.selectionEl.addClass('hide'); 81 } 82 this.selectionElStyle = this.selectionEl[0].style; 83 84 85 this.handle1 = this.picker.find('.slider-handle:first'); 86 this.handle1Stype = this.handle1[0].style; 87 this.handle2 = this.picker.find('.slider-handle:last'); 88 this.handle2Stype = this.handle2[0].style; 89 90 var handle = this.element.data('slider-handle')||options.handle; 91 switch(handle) { 92 case 'round': 93 this.handle1.addClass('round'); 94 this.handle2.addClass('round'); 95 break 96 case 'triangle': 97 this.handle1.addClass('triangle'); 98 this.handle2.addClass('triangle'); 99 break 100 } 101 102 if (this.range) { 103 this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); 104 this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); 105 } else { 106 this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; 107 this.handle2.addClass('hide'); 108 if (this.selection == 'after') { 109 this.value[1] = this.max; 110 } else { 111 this.value[1] = this.min; 112 } 113 } 114 this.diff = this.max - this.min; 115 this.percentage = [ 116 (this.value[0]-this.min)*100/this.diff, 117 (this.value[1]-this.min)*100/this.diff, 118 this.step*100/this.diff 119 ]; 120 121 this.offset = this.picker.offset(); 122 this.size = this.picker[0][this.sizePos]; 123 124 this.formater = options.formater; 125 126 this.layout(); 127 128 if (this.touchCapable) { 129 // Touch: Bind touch events: 130 this.picker.on({ 131 touchstart: $.proxy(this.mousedown, this) 132 }); 133 } else { 134 this.picker.on({ 135 mousedown: $.proxy(this.mousedown, this) 136 }); 137 } 138 139 if (tooltip === 'show') { 140 this.picker.on({ 141 mouseenter: $.proxy(this.showTooltip, this), 142 mouseleave: $.proxy(this.hideTooltip, this) 143 }); 144 } else { 145 this.tooltip.addClass('hide'); 146 } 147 }; 148 149 Slider.prototype = { 150 constructor: Slider, 151 152 over: false, 153 inDrag: false, 154 155 showTooltip: function(){ 156 this.tooltip.addClass('in'); 157 //var left = Math.round(this.percent*this.width); 158 //this.tooltip.css('left', left - this.tooltip.outerWidth()/2); 159 this.over = true; 160 }, 161 162 hideTooltip: function(){ 163 if (this.inDrag === false) { 164 this.tooltip.removeClass('in'); 165 } 166 this.over = false; 167 }, 168 169 layout: function(){ 170 this.handle1Stype[this.stylePos] = this.percentage[0]+'%'; 171 this.handle2Stype[this.stylePos] = this.percentage[1]+'%'; 172 if (this.orientation == 'vertical') { 173 this.selectionElStyle.top = Math.min(this.percentage[0], this.percentage[1]) +'%'; 174 this.selectionElStyle.height = Math.abs(this.percentage[0] - this.percentage[1]) +'%'; 175 } else { 176 this.selectionElStyle.left = Math.min(this.percentage[0], this.percentage[1]) +'%'; 177 this.selectionElStyle.width = Math.abs(this.percentage[0] - this.percentage[1]) +'%'; 178 } 179 if (this.range) { 180 this.tooltipInner.text( 181 this.formater(this.value[0]) + 182 ' : ' + 183 this.formater(this.value[1]) 184 ); 185 this.tooltip[0].style[this.stylePos] = this.size * (this.percentage[0] + (this.percentage[1] - this.percentage[0])/2)/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; 186 } else { 187 this.tooltipInner.text( 188 this.formater(this.value[0]) 189 ); 190 this.tooltip[0].style[this.stylePos] = this.size * this.percentage[0]/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; 191 } 192 }, 193 194 mousedown: function(ev) { 195 196 // Touch: Get the original event: 197 if (this.touchCapable && ev.type === 'touchstart') { 198 ev = ev.originalEvent; 199 } 200 201 this.offset = this.picker.offset(); 202 this.size = this.picker[0][this.sizePos]; 203 204 var percentage = this.getPercentage(ev); 205 206 if (this.range) { 207 var diff1 = Math.abs(this.percentage[0] - percentage); 208 var diff2 = Math.abs(this.percentage[1] - percentage); 209 this.dragged = (diff1 < diff2) ? 0 : 1; 210 } else { 211 this.dragged = 0; 212 } 213 214 this.percentage[this.dragged] = percentage; 215 this.layout(); 216 217 if (this.touchCapable) { 218 // Touch: Bind touch events: 219 $(document).on({ 220 touchmove: $.proxy(this.mousemove, this), 221 touchend: $.proxy(this.mouseup, this) 222 }); 223 } else { 224 $(document).on({ 225 mousemove: $.proxy(this.mousemove, this), 226 mouseup: $.proxy(this.mouseup, this) 227 }); 228 } 229 230 this.inDrag = true; 231 var val = this.calculateValue(); 232 this.element.trigger({ 233 type: 'slideStart', 234 value: val 235 }).trigger({ 236 type: 'slide', 237 value: val 238 }); 239 return false; 240 }, 241 242 mousemove: function(ev) { 243 244 // Touch: Get the original event: 245 if (this.touchCapable && ev.type === 'touchmove') { 246 ev = ev.originalEvent; 247 } 248 249 var percentage = this.getPercentage(ev); 250 if (this.range) { 251 if (this.dragged === 0 && this.percentage[1] < percentage) { 252 this.percentage[0] = this.percentage[1]; 253 this.dragged = 1; 254 } else if (this.dragged === 1 && this.percentage[0] > percentage) { 255 this.percentage[1] = this.percentage[0]; 256 this.dragged = 0; 257 } 258 } 259 this.percentage[this.dragged] = percentage; 260 this.layout(); 261 var val = this.calculateValue(); 262 this.element 263 .trigger({ 264 type: 'slide', 265 value: val 266 }) 267 .data('value', val) 268 .prop('value', val); 269 return false; 270 }, 271 272 mouseup: function(ev) { 273 if (this.touchCapable) { 274 // Touch: Bind touch events: 275 $(document).off({ 276 touchmove: this.mousemove, 277 touchend: this.mouseup 278 }); 279 } else { 280 $(document).off({ 281 mousemove: this.mousemove, 282 mouseup: this.mouseup 283 }); 284 } 285 286 this.inDrag = false; 287 if (this.over == false) { 288 this.hideTooltip(); 289 } 290 this.element; 291 var val = this.calculateValue(); 292 this.element 293 .trigger({ 294 type: 'slideStop', 295 value: val 296 }) 297 .data('value', val) 298 .prop('value', val); 299 return false; 300 }, 301 302 calculateValue: function() { 303 var val; 304 if (this.range) { 305 val = [ 306 (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step), 307 (this.min + Math.round((this.diff * this.percentage[1]/100)/this.step)*this.step) 308 ]; 309 this.value = val; 310 } else { 311 val = (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step); 312 this.value = [val, this.value[1]]; 313 } 314 return val; 315 }, 316 317 getPercentage: function(ev) { 318 if (this.touchCapable) { 319 ev = ev.touches[0]; 320 } 321 var percentage = (ev[this.mousePos] - this.offset[this.stylePos])*100/this.size; 322 percentage = Math.round(percentage/this.percentage[2])*this.percentage[2]; 323 return Math.max(0, Math.min(100, percentage)); 324 }, 325 326 getValue: function() { 327 if (this.range) { 328 return this.value; 329 } 330 return this.value[0]; 331 }, 332 333 setValue: function(val) { 334 this.value = val; 335 336 if (this.range) { 337 this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); 338 this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); 339 } else { 340 this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; 341 this.handle2.addClass('hide'); 342 if (this.selection == 'after') { 343 this.value[1] = this.max; 344 } else { 345 this.value[1] = this.min; 346 } 347 } 348 this.diff = this.max - this.min; 349 this.percentage = [ 350 (this.value[0]-this.min)*100/this.diff, 351 (this.value[1]-this.min)*100/this.diff, 352 this.step*100/this.diff 353 ]; 354 this.layout(); 355 } 356 }; 357 358 $.fn.slider = function ( option, val ) { 359 return this.each(function () { 360 var $this = $(this), 361 data = $this.data('slider'), 362 options = typeof option === 'object' && option; 363 if (!data) { 364 $this.data('slider', (data = new Slider(this, $.extend({}, $.fn.slider.defaults,options)))); 365 } 366 if (typeof option == 'string') { 367 data[option](val); 368 } 369 }) 370 }; 371 372 $.fn.slider.defaults = { 373 min: 0, 374 max: 10, 375 step: 1, 376 orientation: 'horizontal', 377 value: 5, 378 selection: 'before', 379 tooltip: 'show', 380 handle: 'round', 381 formater: function(value) { 382 return value; 383 } 384 }; 385 386 $.fn.slider.Constructor = Slider; 387 388 }( window.jQuery );