240 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			240 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|   | ;(function ($, window, document, undefined) { | ||
|  |   'use strict'; | ||
|  | 
 | ||
|  |   Foundation.libs.slider = { | ||
|  |     name : 'slider', | ||
|  | 
 | ||
|  |     version : '5.4.7', | ||
|  | 
 | ||
|  |     settings: { | ||
|  |       start: 0, | ||
|  |       end: 100, | ||
|  |       step: 1, | ||
|  |       initial: null, | ||
|  |       display_selector: '', | ||
|  |       vertical: false, | ||
|  |       on_change: function(){} | ||
|  |     }, | ||
|  | 
 | ||
|  |     cache : {}, | ||
|  | 
 | ||
|  |     init : function (scope, method, options) { | ||
|  |       Foundation.inherit(this,'throttle'); | ||
|  |       this.bindings(method, options); | ||
|  |       this.reflow(); | ||
|  |     }, | ||
|  | 
 | ||
|  |     events : function() { | ||
|  |       var self = this; | ||
|  | 
 | ||
|  |       $(this.scope) | ||
|  |         .off('.slider') | ||
|  |         .on('mousedown.fndtn.slider touchstart.fndtn.slider pointerdown.fndtn.slider', | ||
|  |         '[' + self.attr_name() + ']:not(.disabled, [disabled]) .range-slider-handle', function(e) { | ||
|  |           if (!self.cache.active) { | ||
|  |             e.preventDefault(); | ||
|  |             self.set_active_slider($(e.target)); | ||
|  |           } | ||
|  |         }) | ||
|  |         .on('mousemove.fndtn.slider touchmove.fndtn.slider pointermove.fndtn.slider', function(e) { | ||
|  |           if (!!self.cache.active) { | ||
|  |             e.preventDefault(); | ||
|  |             if ($.data(self.cache.active[0], 'settings').vertical) { | ||
|  |               var scroll_offset = 0; | ||
|  |               if (!e.pageY) { | ||
|  |                 scroll_offset = window.scrollY; | ||
|  |               } | ||
|  |               self.calculate_position(self.cache.active, (e.pageY ||  | ||
|  |                                                           e.originalEvent.clientY ||  | ||
|  |                                                           e.originalEvent.touches[0].clientY ||  | ||
|  |                                                           e.currentPoint.y)  | ||
|  |                                                           + scroll_offset); | ||
|  |             } else { | ||
|  |               self.calculate_position(self.cache.active, e.pageX ||  | ||
|  |                                                          e.originalEvent.clientX ||  | ||
|  |                                                          e.originalEvent.touches[0].clientX ||  | ||
|  |                                                          e.currentPoint.x); | ||
|  |             } | ||
|  |           } | ||
|  |         }) | ||
|  |         .on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function(e) { | ||
|  |           self.remove_active_slider(); | ||
|  |         }) | ||
|  |         .on('change.fndtn.slider', function(e) { | ||
|  |           self.settings.on_change(); | ||
|  |         }); | ||
|  | 
 | ||
|  |       self.S(window) | ||
|  |         .on('resize.fndtn.slider', self.throttle(function(e) { | ||
|  |           self.reflow(); | ||
|  |         }, 300)); | ||
|  |     }, | ||
|  | 
 | ||
|  |     set_active_slider : function($handle) { | ||
|  |       this.cache.active = $handle; | ||
|  |     }, | ||
|  | 
 | ||
|  |     remove_active_slider : function() { | ||
|  |       this.cache.active = null; | ||
|  |     }, | ||
|  | 
 | ||
|  |     calculate_position : function($handle, cursor_x) { | ||
|  |       var self = this, | ||
|  |           settings = $.data($handle[0], 'settings'), | ||
|  |           handle_l = $.data($handle[0], 'handle_l'), | ||
|  |           handle_o = $.data($handle[0], 'handle_o'), | ||
|  |           bar_l = $.data($handle[0], 'bar_l'), | ||
|  |           bar_o = $.data($handle[0], 'bar_o'); | ||
|  | 
 | ||
|  |       requestAnimationFrame(function(){ | ||
|  |         var pct; | ||
|  | 
 | ||
|  |         if (Foundation.rtl && !settings.vertical) { | ||
|  |           pct = self.limit_to(((bar_o+bar_l-cursor_x)/bar_l),0,1); | ||
|  |         } else { | ||
|  |           pct = self.limit_to(((cursor_x-bar_o)/bar_l),0,1); | ||
|  |         } | ||
|  | 
 | ||
|  |         pct = settings.vertical ? 1-pct : pct; | ||
|  | 
 | ||
|  |         var norm = self.normalized_value(pct, settings.start, settings.end, settings.step); | ||
|  | 
 | ||
|  |         self.set_ui($handle, norm); | ||
|  |       }); | ||
|  |     }, | ||
|  | 
 | ||
|  |     set_ui : function($handle, value) { | ||
|  |       var settings = $.data($handle[0], 'settings'), | ||
|  |           handle_l = $.data($handle[0], 'handle_l'), | ||
|  |           bar_l = $.data($handle[0], 'bar_l'), | ||
|  |           norm_pct = this.normalized_percentage(value, settings.start, settings.end), | ||
|  |           handle_offset = norm_pct*(bar_l-handle_l)-1, | ||
|  |           progress_bar_length = norm_pct*100; | ||
|  | 
 | ||
|  |       if (Foundation.rtl && !settings.vertical) { | ||
|  |         handle_offset = -handle_offset; | ||
|  |       } | ||
|  | 
 | ||
|  |       handle_offset = settings.vertical ? -handle_offset + bar_l - handle_l + 1 : handle_offset; | ||
|  |       this.set_translate($handle, handle_offset, settings.vertical); | ||
|  | 
 | ||
|  |       if (settings.vertical) { | ||
|  |         $handle.siblings('.range-slider-active-segment').css('height', progress_bar_length + '%'); | ||
|  |       } else { | ||
|  |         $handle.siblings('.range-slider-active-segment').css('width', progress_bar_length + '%'); | ||
|  |       } | ||
|  | 
 | ||
|  |       $handle.parent().attr(this.attr_name(), value).trigger('change').trigger('change.fndtn.slider'); | ||
|  | 
 | ||
|  |       $handle.parent().children('input[type=hidden]').val(value); | ||
|  | 
 | ||
|  |       if (!$handle[0].hasAttribute('aria-valuemin')) { | ||
|  |         $handle.attr({ | ||
|  |           'aria-valuemin': settings.start, | ||
|  |           'aria-valuemax': settings.end, | ||
|  |         }); | ||
|  |       } | ||
|  |       $handle.attr('aria-valuenow', value); | ||
|  | 
 | ||
|  |       if (settings.display_selector != '') { | ||
|  |         $(settings.display_selector).each(function(){ | ||
|  |           if (this.hasOwnProperty('value')) { | ||
|  |             $(this).val(value); | ||
|  |           } else { | ||
|  |             $(this).text(value); | ||
|  |           } | ||
|  |         }); | ||
|  |       } | ||
|  | 
 | ||
|  |     }, | ||
|  | 
 | ||
|  |     normalized_percentage : function(val, start, end) { | ||
|  |       return Math.min(1, (val - start)/(end - start)); | ||
|  |     }, | ||
|  | 
 | ||
|  |     normalized_value : function(val, start, end, step) { | ||
|  |       var range = end - start, | ||
|  |           point = val*range, | ||
|  |           mod = (point-(point%step)) / step, | ||
|  |           rem = point % step, | ||
|  |           round = ( rem >= step*0.5 ? step : 0); | ||
|  |       return (mod*step + round) + start; | ||
|  |     }, | ||
|  | 
 | ||
|  |     set_translate : function(ele, offset, vertical) { | ||
|  |       if (vertical) { | ||
|  |         $(ele) | ||
|  |           .css('-webkit-transform', 'translateY('+offset+'px)') | ||
|  |           .css('-moz-transform', 'translateY('+offset+'px)') | ||
|  |           .css('-ms-transform', 'translateY('+offset+'px)') | ||
|  |           .css('-o-transform', 'translateY('+offset+'px)') | ||
|  |           .css('transform', 'translateY('+offset+'px)'); | ||
|  |       } else { | ||
|  |         $(ele) | ||
|  |           .css('-webkit-transform', 'translateX('+offset+'px)') | ||
|  |           .css('-moz-transform', 'translateX('+offset+'px)') | ||
|  |           .css('-ms-transform', 'translateX('+offset+'px)') | ||
|  |           .css('-o-transform', 'translateX('+offset+'px)') | ||
|  |           .css('transform', 'translateX('+offset+'px)'); | ||
|  |       } | ||
|  |     }, | ||
|  | 
 | ||
|  |     limit_to : function(val, min, max) { | ||
|  |       return Math.min(Math.max(val, min), max); | ||
|  |     }, | ||
|  | 
 | ||
|  |     initialize_settings : function(handle) { | ||
|  |       var settings = $.extend({}, this.settings, this.data_options($(handle).parent())); | ||
|  | 
 | ||
|  |       if (settings.vertical) { | ||
|  |         $.data(handle, 'bar_o', $(handle).parent().offset().top); | ||
|  |         $.data(handle, 'bar_l', $(handle).parent().outerHeight()); | ||
|  |         $.data(handle, 'handle_o', $(handle).offset().top); | ||
|  |         $.data(handle, 'handle_l', $(handle).outerHeight()); | ||
|  |       } else { | ||
|  |         $.data(handle, 'bar_o', $(handle).parent().offset().left); | ||
|  |         $.data(handle, 'bar_l', $(handle).parent().outerWidth()); | ||
|  |         $.data(handle, 'handle_o', $(handle).offset().left); | ||
|  |         $.data(handle, 'handle_l', $(handle).outerWidth()); | ||
|  |       } | ||
|  | 
 | ||
|  |       $.data(handle, 'bar', $(handle).parent()); | ||
|  |       $.data(handle, 'settings', settings); | ||
|  |     }, | ||
|  | 
 | ||
|  |     set_initial_position : function($ele) { | ||
|  |       var settings = $.data($ele.children('.range-slider-handle')[0], 'settings'), | ||
|  |           initial = (!!settings.initial ? settings.initial : Math.floor((settings.end-settings.start)*0.5/settings.step)*settings.step+settings.start), | ||
|  |           $handle = $ele.children('.range-slider-handle'); | ||
|  |       this.set_ui($handle, initial); | ||
|  |     }, | ||
|  | 
 | ||
|  |     set_value : function(value) { | ||
|  |       var self = this; | ||
|  |       $('[' + self.attr_name() + ']', this.scope).each(function(){ | ||
|  |         $(this).attr(self.attr_name(), value); | ||
|  |       }); | ||
|  |       if (!!$(this.scope).attr(self.attr_name())) { | ||
|  |         $(this.scope).attr(self.attr_name(), value); | ||
|  |       } | ||
|  |       self.reflow(); | ||
|  |     }, | ||
|  | 
 | ||
|  |     reflow : function() { | ||
|  |       var self = this; | ||
|  |       self.S('[' + this.attr_name() + ']').each(function() { | ||
|  |         var handle = $(this).children('.range-slider-handle')[0], | ||
|  |             val = $(this).attr(self.attr_name()); | ||
|  |         self.initialize_settings(handle); | ||
|  | 
 | ||
|  |         if (val) { | ||
|  |           self.set_ui($(handle), parseFloat(val)); | ||
|  |         } else { | ||
|  |           self.set_initial_position($(this)); | ||
|  |         } | ||
|  |       }); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  | }(jQuery, window, window.document)); |