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));
 |