PageSourceSearch

https://www.nishikofu.co.jp/wp_nkofu/wp-content/themes/nkofu_tm/js/rangeslider/rangeslider.js

js nishikofu.co.jp collected 2026-10-08 02:40:10 UTC 17,985 bytes, 498 lines download raw bytes

vendor: 17,985 bytes, lines 1-498
1/*! rangeslider.js - v2.3.2 | (c) 2018 @andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */
2(function(factory) {
3    'use strict';
4
5    if (typeof define === 'function' && define.amd) {
6        // AMD. Register as an anonymous module.
7        define(['jquery'], factory);
8    } else if (typeof exports === 'object') {
9        // CommonJS
10        module.exports = factory(require('jquery'));
11    } else {
12        // Browser globals
13        factory(jQuery);
14    }
15}(function($) {
16    'use strict';
17
18    // Polyfill Number.isNaN(value)
19    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
20    Number.isNaN = Number.isNaN || function(value) {
21        return typeof value === 'number' && value !== value;
22    };
23
24    /**
25     * Range feature detection
26     * @return {Boolean}
27     */
28    function supportsRange() {
29        var input = document.createElement('input');
30        input.setAttribute('type', 'range');
31        return input.type !== 'text';
32    }
33
34    var pluginName = 'rangeslider',
35        pluginIdentifier = 0,
36        hasInputRangeSupport = supportsRange(),
37        defaults = {
38            polyfill: true,
39            orientation: 'horizontal',
40            rangeClass: 'rangeslider',
41            disabledClass: 'rangeslider--disabled',
42            activeClass: 'rangeslider--active',
43            horizontalClass: 'rangeslider--horizontal',
44            verticalClass: 'rangeslider--vertical',
45            fillClass: 'rangeslider__fill',
46            handleClass: 'rangeslider__handle',
47            startEvent: ['mousedown', 'touchstart', 'pointerdown'],
48            moveEvent: ['mousemove', 'touchmove', 'pointermove'],
49            endEvent: ['mouseup', 'touchend', 'pointerup']
50        },
51        constants = {
52            orientation: {
53                horizontal: {
54                    dimension: 'width',
55                    direction: 'left',
56                    directionStyle: 'left',
57                    coordinate: 'x'
58                },
59                vertical: {
60                    dimension: 'height',
61                    direction: 'top',
62                    directionStyle: 'bottom',
63                    coordinate: 'y'
64                }
65            }
66        };
67
68    /**
69     * Delays a function for the given number of milliseconds, and then calls
70     * it with the arguments supplied.
71     *
72     * @param  {Function} fn   [description]
73     * @param  {Number}   wait [description]
74     * @return {Function}
75     */
76    function delay(fn, wait) {
77        var args = Array.prototype.slice.call(arguments, 2);
78        return setTimeout(function(){ return fn.apply(null, args); }, wait);
79    }
80
81    /**
82     * Returns a debounced function that will make sure the given
83     * function is not triggered too much.
84     *
85     * @param  {Function} fn Function to debounce.
86     * @param  {Number}   debounceDuration OPTIONAL. The amount of time in milliseconds for which we will debounce the function. (defaults to 100ms)
87     * @return {Function}
88     */
89    function debounce(fn, debounceDuration) {
90        debounceDuration = debounceDuration || 100;
91        return function() {
92            if (!fn.debouncing) {
93                var args = Array.prototype.slice.apply(arguments);
94                fn.lastReturnVal = fn.apply(window, args);
95                fn.debouncing = true;
96            }
97            clearTimeout(fn.debounceTimeout);
98            fn.debounceTimeout = setTimeout(function(){
99                fn.debouncing = false;
100            }, debounceDuration);
101            return fn.lastReturnVal;
102        };
103    }
104
105    /**
106     * Check if a `element` is visible in the DOM
107     *
108     * @param  {Element}  element
109     * @return {Boolean}
110     */
111    function isHidden(element) {
112        return (
113            element && (
114                element.offsetWidth === 0 ||
115                element.offsetHeight === 0 ||
116                // Also Consider native `<details>` elements.
117                element.open === false
118            )
119        );
120    }
121
122    /**
123     * Get hidden parentNodes of an `element`
124     *
125     * @param  {Element} element
126     * @return {[type]}
127     */
128    function getHiddenParentNodes(element) {
129        var parents = [],
130            node    = element.parentNode;
131
132        while (isHidden(node)) {
133            parents.push(node);
134            node = node.parentNode;
135        }
136        return parents;
137    }
138
139    /**
140     * Returns dimensions for an element even if it is not visible in the DOM.
141     *
142     * @param  {Element} element
143     * @param  {String}  key     (e.g. offsetWidth …)
144     * @return {Number}
145     */
146    function getDimension(element, key) {
147        var hiddenParentNodes       = getHiddenParentNodes(element),
148            hiddenParentNodesLength = hiddenParentNodes.length,
149            inlineStyle             = [],
150            dimension               = element[key];
151
152        // Used for native `<details>` elements
153        function toggleOpenProperty(element) {
154            if (typeof element.open !== 'undefined') {
155                element.open = (element.open) ? false : true;
156            }
157        }
158
159        if (hiddenParentNodesLength) {
160            for (var i = 0; i < hiddenParentNodesLength; i++) {
161
162                // Cache style attribute to restore it later.
163                inlineStyle[i] = hiddenParentNodes[i].style.cssText;
164
165                // visually hide
166                if (hiddenParentNodes[i].style.setProperty) {
167                    hiddenParentNodes[i].style.setProperty('display', 'block', 'important');
168                } else {
169                    hiddenParentNodes[i].style.cssText += ';display: block !important';
170                }
171                hiddenParentNodes[i].style.height = '0';
172                hiddenParentNodes[i].style.overflow = 'hidden';
173                hiddenParentNodes[i].style.visibility = 'hidden';
174                toggleOpenProperty(hiddenParentNodes[i]);
175            }
176
177            // Update dimension
178            dimension = element[key];
179
180            for (var j = 0; j < hiddenParentNodesLength; j++) {
181
182                // Restore the style attribute
183                hiddenParentNodes[j].style.cssText = inlineStyle[j];
184                toggleOpenProperty(hiddenParentNodes[j]);
185            }
186        }
187        return dimension;
188    }
189
190    /**
191     * Returns the parsed float or the default if it failed.
192     *
193     * @param  {String}  str
194     * @param  {Number}  defaultValue
195     * @return {Number}
196     */
197    function tryParseFloat(str, defaultValue) {
198        var value = parseFloat(str);
199        return Number.isNaN(value) ? defaultValue : value;
200    }
201
202    /**
203     * Capitalize the first letter of string
204     *
205     * @param  {String} str
206     * @return {String}
207     */
208    function ucfirst(str) {
209        return str.charAt(0).toUpperCase() + str.substr(1);
210    }
211
212    /**
213     * Plugin
214     * @param {String} element
215     * @param {Object} options
216     */
217    function Plugin(element, options) {
218        this.$window            = $(window);
219        this.$document          = $(document);
220        this.$element           = $(element);
221        this.options            = $.extend( {}, defaults, options );
222        this.polyfill           = this.options.polyfill;
223        this.orientation        = this.$element[0].getAttribute('data-orientation') || this.options.orientation;
224        this.onInit             = this.options.onInit;
225        this.onSlide            = this.options.onSlide;
226        this.onSlideEnd         = this.options.onSlideEnd;
227        this.DIMENSION          = constants.orientation[this.orientation].dimension;
228        this.DIRECTION          = constants.orientation[this.orientation].direction;
229        this.DIRECTION_STYLE    = constants.orientation[this.orientation].directionStyle;
230        this.COORDINATE         = constants.orientation[this.orientation].coordinate;
231
232        // Plugin should only be used as a polyfill
233        if (this.polyfill) {
234            // Input range support?
235            if (hasInputRangeSupport) { return false; }
236        }
237
238        this.identifier = 'js-' + pluginName + '-' +(pluginIdentifier++);
239        this.startEvent = this.options.startEvent.join('.' + this.identifier + ' ') + '.' + this.identifier;
240        this.moveEvent  = this.options.moveEvent.join('.' + this.identifier + ' ') + '.' + this.identifier;
241        this.endEvent   = this.options.endEvent.join('.' + this.identifier + ' ') + '.' + this.identifier;
242        this.toFixed    = (this.step + '').replace('.', '').length - 1;
243        this.$fill      = $('<div class="' + this.options.fillClass + '" />');
244        this.$handle    = $('<div class="' + this.options.handleClass + '" />');
245        this.$range     = $('<div class="' + this.options.rangeClass + ' ' + this.options[this.orientation + 'Class'] + '" id="' + this.identifier + '" />').insertAfter(this.$element).prepend(this.$fill, this.$handle);
246
247        // visually hide the input
248        this.$element.css({
249            'position': 'absolute',
250            'width': '1px',
251            'height': '1px',
252            'overflow': 'hidden',
253            'opacity': '0'
254        });
255
256        // Store context
257        this.handleDown = $.proxy(this.handleDown, this);
258        this.handleMove = $.proxy(this.handleMove, this);
259        this.handleEnd  = $.proxy(this.handleEnd, this);
260
261        this.init();
262
263        // Attach Events
264        var _this = this;
265        this.$window.on('resize.' + this.identifier, debounce(function() {
266            // Simulate resizeEnd event.
267            delay(function() { _this.update(false, false); }, 300);
268        }, 20));
269
270        this.$document.on(this.startEvent, '#' + this.identifier + ':not(.' + this.options.disabledClass + ')', this.handleDown);
271
272        // Listen to programmatic value changes
273        this.$element.on('change.' + this.identifier, function(e, data) {
274            if (data && data.origin === _this.identifier) {
275                return;
276            }
277
278            var value = e.target.value,
279                pos = _this.getPositionFromValue(value);
280            _this.setPosition(pos);
281        });
282    }
283
284    Plugin.prototype.init = function() {
285        this.update(true, false);
286
287        if (this.onInit && typeof this.onInit === 'function') {
288            this.onInit();
289        }
290    };
291
292    Plugin.prototype.update = function(updateAttributes, triggerSlide) {
293        updateAttributes = updateAttributes || false;
294
295        if (updateAttributes) {
296            this.min    = tryParseFloat(this.$element[0].getAttribute('min'), 0);
297            this.max    = tryParseFloat(this.$element[0].getAttribute('max'), 100);
298            this.value  = tryParseFloat(this.$element[0].value, Math.round(this.min + (this.max-this.min)/2));
299            this.step   = tryParseFloat(this.$element[0].getAttribute('step'), 1);
300        }
301
302        this.handleDimension    = getDimension(this.$handle[0], 'offset' + ucfirst(this.DIMENSION));
303        this.rangeDimension     = getDimension(this.$range[0], 'offset' + ucfirst(this.DIMENSION));
304        this.maxHandlePos       = this.rangeDimension - this.handleDimension;
305        this.grabPos            = this.handleDimension / 2;
306        this.position           = this.getPositionFromValue(this.value);
307
308        // Consider disabled state
309        if (this.$element[0].disabled) {
310            this.$range.addClass(this.options.disabledClass);
311        } else {
312            this.$range.removeClass(this.options.disabledClass);
313        }
314
315        this.setPosition(this.position, triggerSlide);
316    };
317
318    Plugin.prototype.handleDown = function(e) {
319        e.preventDefault();
320
321        // Only respond to mouse main button clicks (usually the left button)
322        if (e.button && e.button !== 0) { return; }
323
324        this.$document.on(this.moveEvent, this.handleMove);
325        this.$document.on(this.endEvent, this.handleEnd);
326
327        // add active class because Firefox is ignoring
328        // the handle:active pseudo selector because of `e.preventDefault();`
329        this.$range.addClass(this.options.activeClass);
330
331        // If we click on the handle don't set the new position
332        if ((' ' + e.target.className + ' ').replace(/[\n\t]/g, ' ').indexOf(this.options.handleClass) > -1) {
333            return;
334        }
335
336        var pos         = this.getRelativePosition(e),
337            rangePos    = this.$range[0].getBoundingClientRect()[this.DIRECTION],
338            handlePos   = this.getPositionFromNode(this.$handle[0]) - rangePos,
339            setPos      = (this.orientation === 'vertical') ? (this.maxHandlePos - (pos - this.grabPos)) : (pos - this.grabPos);
340
341        this.setPosition(setPos);
342
343        if (pos >= handlePos && pos < handlePos + this.handleDimension) {
344            this.grabPos = pos - handlePos;
345        }
346    };
347
348    Plugin.prototype.handleMove = function(e) {
349        e.preventDefault();
350        var pos = this.getRelativePosition(e);
351        var setPos = (this.orientation === 'vertical') ? (this.maxHandlePos - (pos - this.grabPos)) : (pos - this.grabPos);
352        this.setPosition(setPos);
353    };
354
355    Plugin.prototype.handleEnd = function(e) {
356        e.preventDefault();
357        this.$document.off(this.moveEvent, this.handleMove);
358        this.$document.off(this.endEvent, this.handleEnd);
359
360        this.$range.removeClass(this.options.activeClass);
361
362        // Ok we're done fire the change event
363        this.$element.trigger('change', { origin: this.identifier });
364
365        if (this.onSlideEnd && typeof this.onSlideEnd === 'function') {
366            this.onSlideEnd(this.position, this.value);
367        }
368    };
369
370    Plugin.prototype.cap = function(pos, min, max) {
371        if (pos < min) { return min; }
372        if (pos > max) { return max; }
373        return pos;
374    };
375
376    Plugin.prototype.setPosition = function(pos, triggerSlide) {
377        var value, newPos;
378
379        if (triggerSlide === undefined) {
380            triggerSlide = true;
381        }
382
383        // Snapping steps
384        value = this.getValueFromPosition(this.cap(pos, 0, this.maxHandlePos));
385        newPos = this.getPositionFromValue(value);
386
387        // Update ui
388        this.$fill[0].style[this.DIMENSION] = (newPos + this.grabPos) + 'px';
389        this.$handle[0].style[this.DIRECTION_STYLE] = newPos + 'px';
390        this.setValue(value);
391
392        // Update globals
393        this.position = newPos;
394        this.value = value;
395
396        if (triggerSlide && this.onSlide && typeof this.onSlide === 'function') {
397            this.onSlide(newPos, value);
398        }
399    };
400
401    // Returns element position relative to the parent
402    Plugin.prototype.getPositionFromNode = function(node) {
403        var i = 0;
404        while (node !== null) {
405            i += node.offsetLeft;
406            node = node.offsetParent;
407        }
408        return i;
409    };
410
411    Plugin.prototype.getRelativePosition = function(e) {
412        // Get the offset DIRECTION relative to the viewport
413        var ucCoordinate = ucfirst(this.COORDINATE),
414            rangePos = this.$range[0].getBoundingClientRect()[this.DIRECTION],
415            pageCoordinate = 0;
416
417        if (typeof e.originalEvent['client' + ucCoordinate] !== 'undefined') {
418            pageCoordinate = e.originalEvent['client' + ucCoordinate];
419        }
420        else if (
421          e.originalEvent.touches &&
422          e.originalEvent.touches[0] &&
423          typeof e.originalEvent.touches[0]['client' + ucCoordinate] !== 'undefined'
424        ) {
425            pageCoordinate = e.originalEvent.touches[0]['client' + ucCoordinate];
426        }
427        else if(e.currentPoint && typeof e.currentPoint[this.COORDINATE] !== 'undefined') {
428            pageCoordinate = e.currentPoint[this.COORDINATE];
429        }
430
431        return pageCoordinate - rangePos;
432    };
433
434    Plugin.prototype.getPositionFromValue = function(value) {
435        var percentage, pos;
436        percentage = (value - this.min)/(this.max - this.min);
437        pos = (!Number.isNaN(percentage)) ? percentage * this.maxHandlePos : 0;
438        return pos;
439    };
440
441    Plugin.prototype.getValueFromPosition = function(pos) {
442        var percentage, value;
443        percentage = ((pos) / (this.maxHandlePos || 1));
444        value = this.step * Math.round(percentage * (this.max - this.min) / this.step) + this.min;
445        return Number((value).toFixed(this.toFixed));
446    };
447
448    Plugin.prototype.setValue = function(value) {
449        if (value === this.value && this.$element[0].value !== '') {
450            return;
451        }
452
453        // Set the new value and fire the `input` event
454        this.$element
455            .val(value)
456            .trigger('input', { origin: this.identifier });
457    };
458
459    Plugin.prototype.destroy = function() {
460        this.$document.off('.' + this.identifier);
461        this.$window.off('.' + this.identifier);
462
463        this.$element
464            .off('.' + this.identifier)
465            .removeAttr('style')
466            .removeData('plugin_' + pluginName);
467
468        // Remove the generated markup
469        if (this.$range && this.$range.length) {
470            this.$range[0].parentNode.removeChild(this.$range[0]);
471        }
472    };
473
474    // A really lightweight plugin wrapper around the constructor,
475    // preventing against multiple instantiations
476    $.fn[pluginName] = function(options) {
477        var args = Array.prototype.slice.call(arguments, 1);
478
479        return this.each(function() {
480            var $this = $(this),
481                data  = $this.data('plugin_' + pluginName);
482
483            // Create a new instance.
484            if (!data) {
485                $this.data('plugin_' + pluginName, (data = new Plugin(this, options)));
486            }
487
488            // Make it possible to access methods from public.
489            // e.g `$element.rangeslider('method');`
490            if (typeof options === 'string') {
491                data[options].apply(data, args);
492            }
493        });
494    };
495
496    return 'rangeslider.js is available in jQuery context e.g $(selector).rangeslider(options);';
497
498}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.