diff --git a/snap.js b/snap.js index cebf7a0..ed8490f 100755 --- a/snap.js +++ b/snap.js @@ -10,9 +10,9 @@ */ /*jslint browser: true*/ /*global define, module, ender*/ -(function(win, doc) { +(function(win, doc) { 'use strict'; - var Snap = Snap || function(userOpts) { + var Snap = Snap || function(userOpts) { var settings = { element: null, dragger: null, @@ -127,7 +127,7 @@ if (element.addEventListener) { return element.addEventListener(eventName, func, false); } else if (element.attachEvent) { - return element.attachEvent("on" + eventName, func); + return element.attachEvent("on" + eventName, func); } }, removeEvent: function addEvent(element, eventName, func) { @@ -156,7 +156,146 @@ el = el.parentNode; } return null; - } + }, + /** + * Support for legacy browser IE8 and IE9 + */ + legacy : { + init: function() { + utils.legacy.browser.setVersion(utils.legacy.browser.getVersion()); + }, + navigation: { + //Side Navigation (open or closed) + opened: false, + isOpen: function isOpen() { + return utils.legacy.navigation.opened; + }, + setOpen: function setOpen( val ) { + utils.legacy.navigation.opened = val; + }, + + //Orientation (left or right) + side: '', + setSide: function( val ){ + utils.legacy.navigation.side = val; + }, + getSide: function() { + return utils.legacy.navigation.side; + } + }, + browser: { + version: null, + getVersion: function() { + var ver = -1; // Return value assumes failure. + if (navigator.appName == 'Microsoft Internet Explorer') + { + var ua = navigator.userAgent; + var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); + if (re.exec(ua) != null) + ver = parseFloat( RegExp.$1 ); + } + return ver; + }, + setVersion: function( val ) { + utils.legacy.browser.version = val; + } + }, + handleIE: function() { + var side = utils.legacy.navigation.side; + if (utils.legacy.browser.version == 8 || utils.legacy.browser.version == 9){ + if (side === 'left') { + if(utils.legacy.navigation.isOpen()){ + menuStyleOpened = { left: '0px' }; + utils.legacy.navigation.setOpen(false); + }else { + menuStyleOpened = { left: settings.maxPosition + 'px' }; + utils.legacy.navigation.setOpen(true); + } + utils.legacy.animate( settings.element, menuStyleOpened, 500 ); + } else if (side === 'right') { + if(utils.legacy.navigation.isOpen()){ + menuStyleOpened = { left: '0px' }; + utils.legacy.navigation.setOpen(false); + }else { + menuStyleOpened = { left: settings.minPosition + 'px' }; + utils.legacy.navigation.setOpen(true); + } + utils.legacy.animate( settings.element, menuStyleOpened, 500 ); + } + } + }, + handleIETapToClose: function() { + var side = utils.legacy.navigation.side; + if (utils.legacy.browser.version == 8 || utils.legacy.browser.version == 9){ + if (side === 'left') { + if(utils.legacy.navigation.isOpen()){ + menuStyleOpened = { left: '0px' }; + utils.legacy.navigation.setOpen(false); + } + utils.legacy.animate( settings.element, menuStyleOpened, 500 ); + } else if (side === 'right') { + if(utils.legacy.navigation.isOpen()){ + menuStyleOpened = { left: '0px' }; + utils.legacy.navigation.setOpen(false); + } + utils.legacy.animate( settings.element, menuStyleOpened, 500 ); + } + } + }, + getDateNow: function() { + if (utils.legacy.browser.version == 8) { + return +new Date; + } + return Date.Now(); + }, + /** + * Helper method, changes an element style over time. + * http://lab.hakim.se/meny/ + */ + animate: function( element, properties, duration, callback ) { + return (function() { + // Will hold start/end values for all properties + var interpolations = {}; + // Format properties + for( var p in properties ) { + interpolations[p] = { + start: parseFloat( element.style[p] ) || 0, + end: parseFloat( properties[p] ), + unit: ( typeof properties[p] === 'string' && properties[p].match( /px|em|%/gi ) ) ? properties[p].match( /px|em|%/gi )[0] : '' + }; + } + var animationStartTime = utils.legacy.getDateNow(), + animationTimeout; + // Takes one step forward in the animation + function step() { + // Ease out + var progress = 1 - Math.pow( 1 - ( ( utils.legacy.getDateNow() - animationStartTime ) / duration ), 5 ); + // Set style to interpolated value + for( var p in interpolations ) { + var property = interpolations[p]; + element.style[p] = property.start + ( ( property.end - property.start ) * progress ) + property.unit; + } + // Continue as long as we're not done + if( progress < 1 ) { + animationTimeout = setTimeout( step, 1000 / 60 ); + } + else { + callback && callback(); + stop(); + } + } + // Cancels the animation + function stop() { + clearTimeout( animationTimeout ); + } + // Starts the animation + step(); + return { + stop: stop + }; + })(); + } + } }, action = { translate: { @@ -166,16 +305,20 @@ if( !utils.canTransform() ){ return parseInt(settings.element.style.left, 10); } else { - var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/), - ieOffset = 8; - if (matrix) { - matrix = matrix[1].split(','); - if(matrix.length===16){ - index+=ieOffset; - } - return parseInt(matrix[index], 10); - } - return 0; + try { + var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/), + ieOffset = 8; + if (matrix) { + matrix = matrix[1].split(','); + if(matrix.length===16){ + index+=ieOffset; + } + return parseInt(matrix[index], 10); + } + return 0; + } catch (err) { + // Silence unimportant errors in IE8 (getComputedStyle not supported) + } } } }, @@ -199,6 +342,7 @@ cache.translation = n; action.translate.x(n); } else { + cache.easing = true; cache.easingTo = n; @@ -207,8 +351,9 @@ cache.animatingInterval = setInterval(function() { utils.dispatchEvent('animating'); }, 1); - + utils.events.addEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback); + action.translate.x(n); } if(n===0){ @@ -216,6 +361,7 @@ } }, x: function(n) { + if( (settings.disable==='left' && n>0) || (settings.disable==='right' && n<0) ){ return; } @@ -233,13 +379,13 @@ n = 0; } - if( utils.canTransform() ){ - var theTranslate = 'translate3d(' + n + 'px, 0,0)'; - settings.element.style[cache.vendor+'Transform'] = theTranslate; + if( utils.canTransform() ){ + var theTranslate = 'translate3d(' + n + 'px, 0,0)'; + settings.element.style[cache.vendor+'Transform'] = theTranslate; } else { + settings.element.style.width = (win.innerWidth || doc.documentElement.clientWidth)+'px'; - - settings.element.style.left = n+'px'; + settings.element.style.left = n+'px'; settings.element.style.right = ''; } } @@ -417,19 +563,22 @@ if (cache.isDragging) { utils.dispatchEvent('end'); var translated = action.translate.get.matrix(4); - + // Tap Close if (cache.dragWatchers.current === 0 && translated !== 0 && settings.tapToClose) { utils.dispatchEvent('close'); utils.events.prevent(e); action.translate.easeTo(0); - cache.isDragging = false; + cache.isDragging = false; cache.startDragX = 0; + utils.legacy.handleIETapToClose(); return; } - + + // Revealing Left if (cache.simpleStates.opening === 'left') { + // Halfway, Flicking, or Too Far Out if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) { if (cache.simpleStates.flick && cache.simpleStates.towards === 'left') { // Flicking Closed @@ -459,14 +608,17 @@ action.translate.easeTo(0); // Close Right } } + cache.isDragging = false; cache.startDragX = utils.page('X', e); + } } - } + } }, init = function(opts) { if (opts.element) { + utils.legacy.init(); utils.deepExtend(settings, opts); cache.vendor = utils.vendor(); action.drag.listen(); @@ -479,7 +631,7 @@ utils.dispatchEvent('open'); utils.klass.remove(doc.body, 'snapjs-expand-left'); utils.klass.remove(doc.body, 'snapjs-expand-right'); - + if (side === 'left') { cache.simpleStates.opening = 'left'; cache.simpleStates.towards = 'right'; @@ -493,10 +645,14 @@ utils.klass.add(doc.body, 'snapjs-right'); action.translate.easeTo(settings.minPosition); } + + utils.legacy.navigation.setSide(side); + utils.legacy.handleIE(); }; this.close = function() { utils.dispatchEvent('close'); action.translate.easeTo(0); + }; this.expand = function(side){ var to = win.innerWidth || doc.documentElement.clientWidth; @@ -565,4 +721,4 @@ return Snap; }); } -}).call(this, window, document); +}).call(this, window, document); \ No newline at end of file