vendor/assets/javascripts/responsive-nav.js in responsive-nav-rails-1.0.16 vs vendor/assets/javascripts/responsive-nav.js in responsive-nav-rails-1.0.20

- old
+ new

@@ -1,6 +1,6 @@ -/*! responsive-nav.js v1.0.16 +/*! responsive-nav.js v1.0.20 * https://github.com/viljamis/responsive-nav.js * http://responsive-nav.com * * Copyright (c) 2013 @viljamis * Available under the MIT license @@ -36,10 +36,11 @@ var nav, opts, navToggle, styleElement = document.createElement("style"), + hasAnimFinished, navOpen, // fn arg can be an object or a function, thanks to handleEvent // read more at: http://www.thecssninja.com/javascript/handleevent addEvent = function (el, evt, fn, bubble) { @@ -129,11 +130,11 @@ var i; // Default options this.options = { animate: true, // Boolean: Use CSS3 transitions, true or false - transition: 400, // Integer: Speed of the transition, in milliseconds + transition: 350, // Integer: Speed of the transition, in milliseconds label: "Menu", // String: Label for the navigation toggle insert: "after", // String: Insert the toggle before or after the navigation customToggle: "", // Selector: Specify the ID of a custom toggle openPos: "relative", // String: Position of the opened nav, relative or static jsClass: "js", // String: 'JS enabled' class which is added to <html> el @@ -179,94 +180,102 @@ nav.removeAttribute("style"); nav.removeAttribute("aria-hidden"); nav = null; _instance = null; - removeEvent(window, "load", this, false); removeEvent(window, "resize", this, false); - removeEvent(navToggle, "mousedown", this, false); + removeEvent(document.body, "touchmove", this, false); removeEvent(navToggle, "touchstart", this, false); removeEvent(navToggle, "touchend", this, false); removeEvent(navToggle, "keyup", this, false); removeEvent(navToggle, "click", this, false); + removeEvent(navToggle, "mouseup", this, false); if (!opts.customToggle) { navToggle.parentNode.removeChild(navToggle); } else { navToggle.removeAttribute("aria-hidden"); } }, toggle: function () { - if (!navOpen) { - removeClass(nav, "closed"); - addClass(nav, "opened"); - nav.style.position = opts.openPos; - setAttributes(nav, {"aria-hidden": "false"}); + if (hasAnimFinished === true) { + if (!navOpen) { + removeClass(nav, "closed"); + addClass(nav, "opened"); + nav.style.position = opts.openPos; + setAttributes(nav, {"aria-hidden": "false"}); - navOpen = true; - opts.open(); - } else { - removeClass(nav, "opened"); - addClass(nav, "closed"); - setAttributes(nav, {"aria-hidden": "true"}); + navOpen = true; + opts.open(); + } else { + removeClass(nav, "opened"); + addClass(nav, "closed"); + setAttributes(nav, {"aria-hidden": "true"}); - if (opts.animate) { - setTimeout(function () { + if (opts.animate) { + hasAnimFinished = false; + setTimeout(function () { + nav.style.position = "absolute"; + hasAnimFinished = true; + }, opts.transition + 10); + } else { nav.style.position = "absolute"; - }, opts.transition + 10); - } else { - nav.style.position = "absolute"; - } + } - navOpen = false; - opts.close(); + navOpen = false; + opts.close(); + } } }, handleEvent: function (e) { var evt = e || window.event; switch (evt.type) { - case "mousedown": - this._onmousedown(evt); - break; case "touchstart": - this._ontouchstart(evt); + this._onTouchStart(evt); break; + case "touchmove": + this._onTouchMove(evt); + break; case "touchend": - this._ontouchend(evt); + case "mouseup": + this._onTouchEnd(evt); break; - case "keyup": - this._onkeyup(evt); - break; case "click": - this._onclick(evt); + this._preventDefault(evt); break; - case "load": - this._transitions(evt); - this._resize(evt); + case "keyup": + this._onKeyUp(evt); break; case "resize": this._resize(evt); break; } }, // Private methods _init: function () { addClass(nav, "closed"); + hasAnimFinished = true; navOpen = false; + this._createToggle(); + this._transitions(); + this._resize(); - addEvent(window, "load", this, false); addEvent(window, "resize", this, false); - addEvent(navToggle, "mousedown", this, false); + addEvent(document.body, "touchmove", this, false); addEvent(navToggle, "touchstart", this, false); addEvent(navToggle, "touchend", this, false); + addEvent(navToggle, "mouseup", this, false); addEvent(navToggle, "keyup", this, false); addEvent(navToggle, "click", this, false); + + // Init callback + opts.init(); }, _createStyles: function () { if (!styleElement.parentNode) { document.getElementsByTagName("head")[0].appendChild(styleElement); @@ -313,48 +322,54 @@ } else { e.returnValue = false; } }, - _onmousedown: function (e) { - var evt = e || window.event; - // If the user isn't right clicking: - if (!(evt.which === 3 || evt.button === 2)) { - this._preventDefault(e); - this.toggle(e); + _onTouchStart: function (e) { + e.stopPropagation(); + this.startX = e.touches[0].clientX; + this.startY = e.touches[0].clientY; + this.touchHasMoved = false; + removeEvent(navToggle, "mouseup", this, false); + }, + + _onTouchMove: function (e) { + if (Math.abs(e.touches[0].clientX - this.startX) > 10 || + Math.abs(e.touches[0].clientY - this.startY) > 10) { + this.touchHasMoved = true; } }, - _ontouchstart: function (e) { - // Touchstart event fires before - // the mousedown and can wipe it - navToggle.onmousedown = null; + _onTouchEnd: function (e) { this._preventDefault(e); - this.toggle(e); + if (!this.touchHasMoved) { + if (e.type === "touchend") { + this.toggle(e); + // Prevent click on the underlying menu on Android 2.3 + var that = this; + nav.addEventListener("click", that._preventDefault, true); + setTimeout(function () { + nav.removeEventListener("click", that._preventDefault, true); + }, opts.transition + 100); + return; + } else { + var evt = e || window.event; + // If it isn't a right click + if (!(evt.which === 3 || evt.button === 2)) { + this.toggle(e); + } + } + } }, - _ontouchend: function () { - // Prevents ghost click from happening on some Android browsers - var that = this; - nav.addEventListener("click", that._preventDefault, true); - setTimeout(function () { - nav.removeEventListener("click", that._preventDefault, true); - }, opts.transition); - }, - - _onkeyup: function (e) { + _onKeyUp: function (e) { var evt = e || window.event; if (evt.keyCode === 13) { this.toggle(e); } }, - _onclick: function (e) { - // For older browsers (looking at IE) - this._preventDefault(e); - }, - _transitions: function () { if (opts.animate) { var objStyle = nav.style, transition = "max-height " + opts.transition + "ms"; @@ -396,12 +411,9 @@ setAttributes(navToggle, {"aria-hidden": "true"}); setAttributes(nav, {"aria-hidden": "false"}); nav.style.position = opts.openPos; this._removeStyles(); } - - // Init callback - opts.init(); } }; var _instance; \ No newline at end of file