diff --git a/Gruntfile.js b/Gruntfile.js index f35ba8a..928d1c2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -95,12 +95,17 @@ module.exports = function (grunt) { // Increment version bump: { options: { - files: ['bower.json', 'package.json'], + files: [ + 'bower.json', + 'package.json', + 'rangeslider.jquery.json' + ], updateConfigs: ['pkg'], commitMessage: 'chore(release): v%VERSION%', commitFiles: [ 'bower.json', 'package.json', + 'rangeslider.jquery.json', 'dist' ], createTag: false diff --git a/bower.json b/bower.json index 543b24d..80b9d7e 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "rangeslider.js", - "version": "0.3.4", + "version": "0.3.5", "homepage": "https://github.com/andreruffert/rangeslider.js", "authors": [ "André Ruffert " diff --git a/dist/rangeslider.js b/dist/rangeslider.js index 1531b77..7cba115 100644 --- a/dist/rangeslider.js +++ b/dist/rangeslider.js @@ -1,4 +1,4 @@ -/*! rangeslider.js - v0.3.4 | (c) 2014 @andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */ +/*! rangeslider.js - v0.3.5 | (c) 2014 @andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */ (function(factory) { 'use strict'; @@ -78,6 +78,72 @@ }; } + /** + * Check if a `element` is visible in the DOM + * + * @param {Element} element + * @return {Boolean} + */ + function isHidden(element) { + if (element.offsetWidth !== 0 || element.offsetHeight !== 0) { + return false; + } + return true; + } + + /** + * Get hidden parentNodes of an `element` + * + * @param {Element} element + * @return {[type]} + */ + function getHiddenParentNodes(element) { + var parents = [], + node = element.parentNode; + + while (isHidden(node)) { + parents.push(node); + node = node.parentNode; + } + return parents; + } + + /** + * Returns dimensions for an element even if it is not visible in the DOM. + * + * @param {Element} element + * @param {String} key (e.g. offsetWidth …) + * @return {Number} + */ + function getDimension(element, key) { + var hiddenParentNodes = getHiddenParentNodes(element), + hiddenParentNodesLength = hiddenParentNodes.length, + displayProperty = [], + dimension = element[key]; + + if (hiddenParentNodesLength) { + for (var i = 0; i < hiddenParentNodesLength; i++) { + // Cache the display property to restore it later. + displayProperty[i] = hiddenParentNodes[i].style.display; + + hiddenParentNodes[i].style.display = 'block'; + hiddenParentNodes[i].style.height = '0'; + hiddenParentNodes[i].style.overflow = 'hidden'; + hiddenParentNodes[i].style.visibility = 'hidden'; + } + + dimension = element[key]; + + for (var j = 0; j < hiddenParentNodesLength; j++) { + hiddenParentNodes[j].style.display = displayProperty[j]; + hiddenParentNodes[j].style.height = ''; + hiddenParentNodes[j].style.overflow = ''; + hiddenParentNodes[j].style.visibility = ''; + } + } + return dimension; + } + /** * Plugin * @param {String} element @@ -158,8 +224,8 @@ }; Plugin.prototype.update = function() { - this.handleWidth = this.$handle[0].offsetWidth; - this.rangeWidth = this.$range[0].offsetWidth; + this.handleWidth = getDimension(this.$handle[0], 'offsetWidth'); + this.rangeWidth = getDimension(this.$range[0], 'offsetWidth'); this.maxHandleX = this.rangeWidth - this.handleWidth; this.grabX = this.handleWidth / 2; this.position = this.getPositionFromValue(this.value); @@ -264,7 +330,7 @@ Plugin.prototype.getValueFromPosition = function(pos) { var percentage, value; percentage = ((pos) / (this.maxHandleX || 1)); - value = this.step * Math.ceil((((percentage) * (this.max - this.min)) + this.min) / this.step); + value = this.step * Math.round(percentage * (this.max - this.min) / this.step) + this.min; return Number((value).toFixed(2)); }; diff --git a/dist/rangeslider.min.js b/dist/rangeslider.min.js index f8a3381..e150bba 100644 --- a/dist/rangeslider.min.js +++ b/dist/rangeslider.min.js @@ -1,2 +1,2 @@ -/*! rangeslider.js - v0.3.4 | (c) 2014 @andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */ -!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){"use strict";function b(){var a=document.createElement("input");return a.setAttribute("type","range"),"text"!==a.type}function c(a,b){var c=Array.prototype.slice.call(arguments,2);return setTimeout(function(){return a.apply(null,c)},b)}function d(a,b){return b=b||100,function(){if(!a.debouncing){var c=Array.prototype.slice.apply(arguments);a.lastReturnVal=a.apply(window,c),a.debouncing=!0}return clearTimeout(a.debounceTimeout),a.debounceTimeout=setTimeout(function(){a.debouncing=!1},b),a.lastReturnVal}}function e(b,e){if(this.$window=a(window),this.$document=a(document),this.$element=a(b),this.options=a.extend({},j,e),this._defaults=j,this._name=f,this.startEvent=this.options.startEvent.join("."+f+" ")+"."+f,this.moveEvent=this.options.moveEvent.join("."+f+" ")+"."+f,this.endEvent=this.options.endEvent.join("."+f+" ")+"."+f,this.polyfill=this.options.polyfill,this.onInit=this.options.onInit,this.onSlide=this.options.onSlide,this.onSlideEnd=this.options.onSlideEnd,this.polyfill&&i)return!1;this.identifier="js-"+f+"-"+h++,this.min=parseFloat(this.$element[0].getAttribute("min")||0),this.max=parseFloat(this.$element[0].getAttribute("max")||100),this.value=parseFloat(this.$element[0].value||this.min+(this.max-this.min)/2),this.step=parseFloat(this.$element[0].getAttribute("step")||1),this.$fill=a('
'),this.$handle=a('
'),this.$range=a('
').insertAfter(this.$element).prepend(this.$fill,this.$handle),this.$element.css({position:"absolute",width:"1px",height:"1px",overflow:"hidden",opacity:"0"}),this.handleDown=a.proxy(this.handleDown,this),this.handleMove=a.proxy(this.handleMove,this),this.handleEnd=a.proxy(this.handleEnd,this),this.init();var g=this;this.$window.on("resize."+f,d(function(){c(function(){g.update()},300)},20)),this.$document.on(this.startEvent,"#"+this.identifier+":not(."+this.options.disabledClass+")",this.handleDown),this.$element.on("change."+f,function(a,b){if(!b||b.origin!==f){var c=a.target.value,d=g.getPositionFromValue(c);g.setPosition(d)}})}var f="rangeslider",g=[],h=0,i=b(),j={polyfill:!0,rangeClass:"rangeslider",disabledClass:"rangeslider--disabled",fillClass:"rangeslider__fill",handleClass:"rangeslider__handle",startEvent:["mousedown","touchstart","pointerdown"],moveEvent:["mousemove","touchmove","pointermove"],endEvent:["mouseup","touchend","pointerup"]};e.prototype.init=function(){this.onInit&&"function"==typeof this.onInit&&this.onInit(),this.update()},e.prototype.update=function(){this.handleWidth=this.$handle[0].offsetWidth,this.rangeWidth=this.$range[0].offsetWidth,this.maxHandleX=this.rangeWidth-this.handleWidth,this.grabX=this.handleWidth/2,this.position=this.getPositionFromValue(this.value),this.$element[0].disabled?this.$range.addClass(this.options.disabledClass):this.$range.removeClass(this.options.disabledClass),this.setPosition(this.position)},e.prototype.handleDown=function(a){if(a.preventDefault(),this.$document.on(this.moveEvent,this.handleMove),this.$document.on(this.endEvent,this.handleEnd),!((" "+a.target.className+" ").replace(/[\n\t]/g," ").indexOf(this.options.handleClass)>-1)){var b=this.getRelativePosition(a),c=this.$range[0].getBoundingClientRect().left,d=this.getPositionFromNode(this.$handle[0])-c;this.setPosition(b-this.grabX),b>=d&&ba?b:a>c?c:a},e.prototype.setPosition=function(a){var b,c;b=this.getValueFromPosition(this.cap(a,0,this.maxHandleX))/this.step*this.step,c=this.getPositionFromValue(b),this.$fill[0].style.width=c+this.grabX+"px",this.$handle[0].style.left=c+"px",this.setValue(b),this.position=c,this.value=b,this.onSlide&&"function"==typeof this.onSlide&&this.onSlide(c,b)},e.prototype.getPositionFromNode=function(a){for(var b=0;null!==a;)b+=a.offsetLeft,a=a.offsetParent;return b},e.prototype.getRelativePosition=function(a){var b=this.$range[0].getBoundingClientRect().left;return(a.pageX||a.originalEvent.clientX||a.originalEvent.touches[0].clientX||a.currentPoint.x)-b},e.prototype.getPositionFromValue=function(a){var b,c;return b=(a-this.min)/(this.max-this.min),c=b*this.maxHandleX},e.prototype.getValueFromPosition=function(a){var b,c;return b=a/(this.maxHandleX||1),c=this.step*Math.ceil((b*(this.max-this.min)+this.min)/this.step),Number(c.toFixed(2))},e.prototype.setValue=function(a){a!==this.value&&this.$element.val(a).trigger("change",{origin:f})},e.prototype.destroy=function(){this.$document.off(this.startEvent,"#"+this.identifier,this.handleDown),this.$element.off("."+f).removeAttr("style").removeData("plugin_"+f),this.$range&&this.$range.length&&this.$range[0].parentNode.removeChild(this.$range[0]),g.splice(g.indexOf(this.$element[0]),1),g.length||this.$window.off("."+f)},a.fn[f]=function(b){return this.each(function(){var c=a(this),d=c.data("plugin_"+f);d||(c.data("plugin_"+f,d=new e(this,b)),g.push(this)),"string"==typeof b&&d[b]()})}}); \ No newline at end of file +/*! rangeslider.js - v0.3.5 | (c) 2014 @andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */ +!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){"use strict";function b(){var a=document.createElement("input");return a.setAttribute("type","range"),"text"!==a.type}function c(a,b){var c=Array.prototype.slice.call(arguments,2);return setTimeout(function(){return a.apply(null,c)},b)}function d(a,b){return b=b||100,function(){if(!a.debouncing){var c=Array.prototype.slice.apply(arguments);a.lastReturnVal=a.apply(window,c),a.debouncing=!0}return clearTimeout(a.debounceTimeout),a.debounceTimeout=setTimeout(function(){a.debouncing=!1},b),a.lastReturnVal}}function e(a){return 0!==a.offsetWidth||0!==a.offsetHeight?!1:!0}function f(a){for(var b=[],c=a.parentNode;e(c);)b.push(c),c=c.parentNode;return b}function g(a,b){var c=f(a),d=c.length,e=[],g=a[b];if(d){for(var h=0;d>h;h++)e[h]=c[h].style.display,c[h].style.display="block",c[h].style.height="0",c[h].style.overflow="hidden",c[h].style.visibility="hidden";g=a[b];for(var i=0;d>i;i++)c[i].style.display=e[i],c[i].style.height="",c[i].style.overflow="",c[i].style.visibility=""}return g}function h(b,e){if(this.$window=a(window),this.$document=a(document),this.$element=a(b),this.options=a.extend({},m,e),this._defaults=m,this._name=i,this.startEvent=this.options.startEvent.join("."+i+" ")+"."+i,this.moveEvent=this.options.moveEvent.join("."+i+" ")+"."+i,this.endEvent=this.options.endEvent.join("."+i+" ")+"."+i,this.polyfill=this.options.polyfill,this.onInit=this.options.onInit,this.onSlide=this.options.onSlide,this.onSlideEnd=this.options.onSlideEnd,this.polyfill&&l)return!1;this.identifier="js-"+i+"-"+k++,this.min=parseFloat(this.$element[0].getAttribute("min")||0),this.max=parseFloat(this.$element[0].getAttribute("max")||100),this.value=parseFloat(this.$element[0].value||this.min+(this.max-this.min)/2),this.step=parseFloat(this.$element[0].getAttribute("step")||1),this.$fill=a('
'),this.$handle=a('
'),this.$range=a('
').insertAfter(this.$element).prepend(this.$fill,this.$handle),this.$element.css({position:"absolute",width:"1px",height:"1px",overflow:"hidden",opacity:"0"}),this.handleDown=a.proxy(this.handleDown,this),this.handleMove=a.proxy(this.handleMove,this),this.handleEnd=a.proxy(this.handleEnd,this),this.init();var f=this;this.$window.on("resize."+i,d(function(){c(function(){f.update()},300)},20)),this.$document.on(this.startEvent,"#"+this.identifier+":not(."+this.options.disabledClass+")",this.handleDown),this.$element.on("change."+i,function(a,b){if(!b||b.origin!==i){var c=a.target.value,d=f.getPositionFromValue(c);f.setPosition(d)}})}var i="rangeslider",j=[],k=0,l=b(),m={polyfill:!0,rangeClass:"rangeslider",disabledClass:"rangeslider--disabled",fillClass:"rangeslider__fill",handleClass:"rangeslider__handle",startEvent:["mousedown","touchstart","pointerdown"],moveEvent:["mousemove","touchmove","pointermove"],endEvent:["mouseup","touchend","pointerup"]};h.prototype.init=function(){this.onInit&&"function"==typeof this.onInit&&this.onInit(),this.update()},h.prototype.update=function(){this.handleWidth=g(this.$handle[0],"offsetWidth"),this.rangeWidth=g(this.$range[0],"offsetWidth"),this.maxHandleX=this.rangeWidth-this.handleWidth,this.grabX=this.handleWidth/2,this.position=this.getPositionFromValue(this.value),this.$element[0].disabled?this.$range.addClass(this.options.disabledClass):this.$range.removeClass(this.options.disabledClass),this.setPosition(this.position)},h.prototype.handleDown=function(a){if(a.preventDefault(),this.$document.on(this.moveEvent,this.handleMove),this.$document.on(this.endEvent,this.handleEnd),!((" "+a.target.className+" ").replace(/[\n\t]/g," ").indexOf(this.options.handleClass)>-1)){var b=this.getRelativePosition(a),c=this.$range[0].getBoundingClientRect().left,d=this.getPositionFromNode(this.$handle[0])-c;this.setPosition(b-this.grabX),b>=d&&ba?b:a>c?c:a},h.prototype.setPosition=function(a){var b,c;b=this.getValueFromPosition(this.cap(a,0,this.maxHandleX))/this.step*this.step,c=this.getPositionFromValue(b),this.$fill[0].style.width=c+this.grabX+"px",this.$handle[0].style.left=c+"px",this.setValue(b),this.position=c,this.value=b,this.onSlide&&"function"==typeof this.onSlide&&this.onSlide(c,b)},h.prototype.getPositionFromNode=function(a){for(var b=0;null!==a;)b+=a.offsetLeft,a=a.offsetParent;return b},h.prototype.getRelativePosition=function(a){var b=this.$range[0].getBoundingClientRect().left;return(a.pageX||a.originalEvent.clientX||a.originalEvent.touches[0].clientX||a.currentPoint.x)-b},h.prototype.getPositionFromValue=function(a){var b,c;return b=(a-this.min)/(this.max-this.min),c=b*this.maxHandleX},h.prototype.getValueFromPosition=function(a){var b,c;return b=a/(this.maxHandleX||1),c=this.step*Math.round(b*(this.max-this.min)/this.step)+this.min,Number(c.toFixed(2))},h.prototype.setValue=function(a){a!==this.value&&this.$element.val(a).trigger("change",{origin:i})},h.prototype.destroy=function(){this.$document.off(this.startEvent,"#"+this.identifier,this.handleDown),this.$element.off("."+i).removeAttr("style").removeData("plugin_"+i),this.$range&&this.$range.length&&this.$range[0].parentNode.removeChild(this.$range[0]),j.splice(j.indexOf(this.$element[0]),1),j.length||this.$window.off("."+i)},a.fn[i]=function(b){return this.each(function(){var c=a(this),d=c.data("plugin_"+i);d||(c.data("plugin_"+i,d=new h(this,b)),j.push(this)),"string"==typeof b&&d[b]()})}}); \ No newline at end of file diff --git a/example/index.html b/example/index.html index e246c2f..adf72be 100644 --- a/example/index.html +++ b/example/index.html @@ -115,6 +115,18 @@

Destroy a plugin instance

+
+
+ +
+

Consider initialization and update of hidden elements

+
+ + +
+ +
+