/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ window.matchMedia=window.matchMedia||function(a){"use strict";var c,d=a.documentElement,e=d.firstElementChild||d.firstChild,f=a.createElement("body"),g=a.createElement("div");return g.id="mq-test-1",g.style.cssText="position:absolute;top:-100em",f.style.background="none",f.appendChild(g),function(a){return g.innerHTML='­',d.insertBefore(f,e),c=42===g.offsetWidth,d.removeChild(f),{matches:c,media:a}}}(document); /*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ (function(a){"use strict";function x(){u(!0)}var b={};if(a.respond=b,b.update=function(){},b.mediaQueriesSupported=a.matchMedia&&a.matchMedia("only all").matches,!b.mediaQueriesSupported){var q,r,t,c=a.document,d=c.documentElement,e=[],f=[],g=[],h={},i=30,j=c.getElementsByTagName("head")[0]||d,k=c.getElementsByTagName("base")[0],l=j.getElementsByTagName("link"),m=[],n=function(){for(var b=0;l.length>b;b++){var c=l[b],d=c.href,e=c.media,f=c.rel&&"stylesheet"===c.rel.toLowerCase();d&&f&&!h[d]&&(c.styleSheet&&c.styleSheet.rawCssText?(p(c.styleSheet.rawCssText,d,e),h[d]=!0):(!/^([a-zA-Z:]*\/\/)/.test(d)&&!k||d.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&m.push({href:d,media:e}))}o()},o=function(){if(m.length){var b=m.shift();v(b.href,function(c){p(c,b.href,b.media),h[b.href]=!0,a.setTimeout(function(){o()},0)})}},p=function(a,b,c){var d=a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),g=d&&d.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+b+"$2$3")},i=!g&&c;b.length&&(b+="/"),i&&(g=1);for(var j=0;g>j;j++){var k,l,m,n;i?(k=c,f.push(h(a))):(k=d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,f.push(RegExp.$2&&h(RegExp.$2))),m=k.split(","),n=m.length;for(var o=0;n>o;o++)l=m[o],e.push({media:l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:f.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},s=function(){var a,b=c.createElement("div"),e=c.body,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",e||(e=f=c.createElement("body"),e.style.background="none"),e.appendChild(b),d.insertBefore(e,d.firstChild),a=b.offsetWidth,f?d.removeChild(e):e.removeChild(b),a=t=parseFloat(a)},u=function(b){var h="clientWidth",k=d[h],m="CSS1Compat"===c.compatMode&&k||c.body[h]||k,n={},o=l[l.length-1],p=(new Date).getTime();if(b&&q&&i>p-q)return a.clearTimeout(r),r=a.setTimeout(u,i),void 0;q=p;for(var v in e)if(e.hasOwnProperty(v)){var w=e[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?t||s():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?t||s():1)),w.hasquery&&(z&&A||!(z||m>=x)||!(A||y>=m))||(n[w.media]||(n[w.media]=[]),n[w.media].push(f[w.rules]))}for(var C in g)g.hasOwnProperty(C)&&g[C]&&g[C].parentNode===j&&j.removeChild(g[C]);for(var D in n)if(n.hasOwnProperty(D)){var E=c.createElement("style"),F=n[D].join("\n");E.type="text/css",E.media=D,j.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(c.createTextNode(F)),g.push(E)}},v=function(a,b){var c=w();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},w=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}();n(),b.update=n,a.addEventListener?a.addEventListener("resize",x,!1):a.attachEvent&&a.attachEvent("onresize",x)}})(this); /*! * skrollr core * * Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr * * Free to use under terms of MIT license */ (function(window, document, undefined) { 'use strict'; /* * Global api. */ var skrollr = window.skrollr = { get: function() { return _instance; }, //Main entry point. init: function(options) { return _instance || new Skrollr(options); }, VERSION: '0.6.12' }; //Minify optimization. var hasProp = Object.prototype.hasOwnProperty; var Math = window.Math; var getStyle = window.getComputedStyle; //They will be filled when skrollr gets initialized. var documentElement; var body; var EVENT_TOUCHSTART = 'touchstart'; var EVENT_TOUCHMOVE = 'touchmove'; var EVENT_TOUCHCANCEL = 'touchcancel'; var EVENT_TOUCHEND = 'touchend'; var SKROLLABLE_CLASS = 'skrollable'; var SKROLLABLE_BEFORE_CLASS = SKROLLABLE_CLASS + '-before'; var SKROLLABLE_BETWEEN_CLASS = SKROLLABLE_CLASS + '-between'; var SKROLLABLE_AFTER_CLASS = SKROLLABLE_CLASS + '-after'; var SKROLLR_CLASS = 'skrollr'; var NO_SKROLLR_CLASS = 'no-' + SKROLLR_CLASS; var SKROLLR_DESKTOP_CLASS = SKROLLR_CLASS + '-desktop'; var SKROLLR_MOBILE_CLASS = SKROLLR_CLASS + '-mobile'; var DEFAULT_EASING = 'linear'; var DEFAULT_DURATION = 1000;//ms var DEFAULT_MOBILE_DECELERATION = 0.004;//pixel/msĀ² var DEFAULT_SMOOTH_SCROLLING_DURATION = 200;//ms var ANCHOR_START = 'start'; var ANCHOR_END = 'end'; var ANCHOR_CENTER = 'center'; var ANCHOR_BOTTOM = 'bottom'; //The property which will be added to the DOM element to hold the ID of the skrollable. var SKROLLABLE_ID_DOM_PROPERTY = '___skrollable_id'; var rxTrim = /^\s+|\s+$/g; //Find all data-attributes. data-[_constant]-[offset]-[anchor]-[anchor]. var rxKeyframeAttribute = /^data(?:-(_\w+))?(?:-?(-?\d+))?(?:-?(start|end|top|center|bottom))?(?:-?(top|center|bottom))?$/; var rxPropValue = /\s*([\w\-\[\]]+)\s*:\s*(.+?)\s*(?:;|$)/gi; //Easing function names follow the property in square brackets. var rxPropEasing = /^([a-z\-]+)\[(\w+)\]$/; var rxCamelCase = /-([a-z])/g; var rxCamelCaseFn = function(str, letter) { return letter.toUpperCase(); }; //Numeric values with optional sign. var rxNumericValue = /[\-+]?[\d]*\.?[\d]+/g; //Used to replace occurences of {?} with a number. var rxInterpolateString = /\{\?\}/g; //Finds rgb(a) colors, which don't use the percentage notation. var rxRGBAIntegerColor = /rgba?\(\s*-?\d+\s*,\s*-?\d+\s*,\s*-?\d+/g; //Finds all gradients. var rxGradient = /[a-z\-]+-gradient/g; //Vendor prefix. Will be set once skrollr gets initialized. var theCSSPrefix = ''; var theDashedCSSPrefix = ''; //Will be called once (when skrollr gets initialized). var detectCSSPrefix = function() { //Only relevant prefixes. May be extended. //Could be dangerous if there will ever be a CSS property which actually starts with "ms". Don't hope so. var rxPrefixes = /^(?:O|Moz|webkit|ms)|(?:-(?:o|moz|webkit|ms)-)/; //Detect prefix for current browser by finding the first property using a prefix. if(!getStyle) { return; } var style = getStyle(body, null); for(var k in style) { //We check the key and if the key is a number, we check the value as well, because safari's getComputedStyle returns some weird array-like thingy. theCSSPrefix = (k.match(rxPrefixes) || (+k == k && style[k].match(rxPrefixes))); if(theCSSPrefix) { break; } } //Did we even detect a prefix? if(!theCSSPrefix) { theCSSPrefix = theDashedCSSPrefix = ''; return; } theCSSPrefix = theCSSPrefix[0]; //We could have detected either a dashed prefix or this camelCaseish-inconsistent stuff. if(theCSSPrefix.slice(0,1) === '-') { theDashedCSSPrefix = theCSSPrefix; //There's no logic behind these. Need a look up. theCSSPrefix = ({ '-webkit-': 'webkit', '-moz-': 'Moz', '-ms-': 'ms', '-o-': 'O' })[theCSSPrefix]; } else { theDashedCSSPrefix = '-' + theCSSPrefix.toLowerCase() + '-'; } }; var polyfillRAF = function() { var requestAnimFrame = window.requestAnimationFrame || window[theCSSPrefix.toLowerCase() + 'RequestAnimationFrame']; var lastTime = _now(); if(_isMobile || !requestAnimFrame) { requestAnimFrame = function(callback) { //How long did it take to render? var deltaTime = _now() - lastTime; var delay = Math.max(0, 1000 / 60 - deltaTime); return window.setTimeout(function() { lastTime = _now(); callback(); }, delay); }; } return requestAnimFrame; }; var polyfillCAF = function() { var cancelAnimFrame = window.cancelAnimationFrame || window[theCSSPrefix.toLowerCase() + 'CancelAnimationFrame']; if(_isMobile || !cancelAnimFrame) { cancelAnimFrame = function(timeout) { return window.clearTimeout(timeout); }; } return cancelAnimFrame; }; //Built-in easing functions. var easings = { begin: function() { return 0; }, end: function() { return 1; }, linear: function(p) { return p; }, quadratic: function(p) { return p * p; }, cubic: function(p) { return p * p * p; }, swing: function(p) { return (-Math.cos(p * Math.PI) / 2) + 0.5; }, sqrt: function(p) { return Math.sqrt(p); }, outCubic: function(p) { return (Math.pow((p - 1), 3) + 1); }, //see https://www.desmos.com/calculator/tbr20s8vd2 for how I did this bounce: function(p) { var a; if(p <= 0.5083) { a = 3; } else if(p <= 0.8489) { a = 9; } else if(p <= 0.96208) { a = 27; } else if(p <= 0.99981) { a = 91; } else { return 1; } return 1 - Math.abs(3 * Math.cos(p * a * 1.028) / a); } }; /** * Constructor. */ function Skrollr(options) { documentElement = document.documentElement; body = document.body; detectCSSPrefix(); _instance = this; options = options || {}; _constants = options.constants || {}; //We allow defining custom easings or overwrite existing. if(options.easing) { for(var e in options.easing) { easings[e] = options.easing[e]; } } _edgeStrategy = options.edgeStrategy || 'set'; _listeners = { //Function to be called right before rendering. beforerender: options.beforerender, //Function to be called right after finishing rendering. render: options.render }; //forceHeight is true by default _forceHeight = options.forceHeight !== false; if(_forceHeight) { _scale = options.scale || 1; } _mobileDeceleration = options.mobileDeceleration || DEFAULT_MOBILE_DECELERATION; _smoothScrollingEnabled = options.smoothScrolling !== false; _smoothScrollingDuration = options.smoothScrollingDuration || DEFAULT_SMOOTH_SCROLLING_DURATION; //Dummy object. Will be overwritten in the _render method when smooth scrolling is calculated. _smoothScrolling = { targetTop: _instance.getScrollTop() }; //A custom check function may be passed. _isMobile = ((options.mobileCheck || function() { return (/Android|iPhone|iPad|iPod|BlackBerry|Windows Phone/i).test(navigator.userAgent || navigator.vendor || window.opera); })()); if(_isMobile) { _skrollrBody = document.getElementById('skrollr-body'); //Detect 3d transform if there's a skrollr-body (only needed for #skrollr-body). if(_skrollrBody) { _detect3DTransforms(); } //_initMobile(); _updateClass(documentElement, [SKROLLR_CLASS, SKROLLR_MOBILE_CLASS], [NO_SKROLLR_CLASS]); } else { _updateClass(documentElement, [SKROLLR_CLASS, SKROLLR_DESKTOP_CLASS], [NO_SKROLLR_CLASS]); } //Triggers parsing of elements and a first reflow. _instance.refresh(); _addEvent(window, 'resize orientationchange', function() { var width = documentElement.clientWidth; var height = documentElement.clientHeight; //Only reflow if the size actually changed (#271). if(height !== _lastViewportHeight || width !== _lastViewportWidth) { _lastViewportHeight = height; _lastViewportWidth = width; _requestReflow = true; } }); var requestAnimFrame = polyfillRAF(); //Let's go. (function animloop(){ _render(); _animFrame = requestAnimFrame(animloop); }()); return _instance; } /** * (Re)parses some or all elements. */ Skrollr.prototype.refresh = function(elements) { var elementIndex; var elementsLength; var ignoreID = false; //Completely reparse anything without argument. if(elements === undefined) { //Ignore that some elements may already have a skrollable ID. ignoreID = true; _skrollables = []; _skrollableIdCounter = 0; elements = document.getElementsByTagName('*'); } else { //We accept a single element or an array of elements. elements = [].concat(elements); } elementIndex = 0; elementsLength = elements.length; for(; elementIndex < elementsLength; elementIndex++) { var el = elements[elementIndex]; var anchorTarget = el; var keyFrames = []; //If this particular element should be smooth scrolled. var smoothScrollThis = _smoothScrollingEnabled; //The edge strategy for this particular element. var edgeStrategy = _edgeStrategy; if(!el.attributes) { continue; } //Iterate over all attributes and search for key frame attributes. var attributeIndex = 0; var attributesLength = el.attributes.length; for (; attributeIndex < attributesLength; attributeIndex++) { var attr = el.attributes[attributeIndex]; if(attr.name === 'data-anchor-target') { anchorTarget = document.querySelector(attr.value); if(anchorTarget === null) { throw 'Unable to find anchor target "' + attr.value + '"'; } continue; } //Global smooth scrolling can be overridden by the element attribute. if(attr.name === 'data-smooth-scrolling') { smoothScrollThis = attr.value !== 'off'; continue; } //Global edge strategy can be overridden by the element attribute. if(attr.name === 'data-edge-strategy') { edgeStrategy = attr.value; continue; } var match = attr.name.match(rxKeyframeAttribute); if(match === null) { continue; } var constant = match[1]; //If there is a constant, get it's value or fall back to 0. constant = constant && _constants[constant.substr(1)] || 0; //Parse key frame offset. If undefined will be casted to 0. var offset = (match[2] | 0) + constant; var anchor1 = match[3]; //If second anchor is not set, the first will be taken for both. var anchor2 = match[4] || anchor1; var kf = { offset: offset, props: attr.value, //Point back to the element as well. element: el }; keyFrames.push(kf); //"absolute" (or "classic") mode, where numbers mean absolute scroll offset. if(!anchor1 || anchor1 === ANCHOR_START || anchor1 === ANCHOR_END) { kf.mode = 'absolute'; //data-end needs to be calculated after all key frames are know. if(anchor1 === ANCHOR_END) { kf.isEnd = true; } else { //For data-start we can already set the key frame w/o calculations. //#59: "scale" options should only affect absolute mode. kf.frame = offset * _scale; delete kf.offset; } } //"relative" mode, where numbers are relative to anchors. else { kf.mode = 'relative'; kf.anchors = [anchor1, anchor2]; } } //Does this element have key frames? if(!keyFrames.length) { continue; } //Will hold the original style and class attributes before we controlled the element (see #80). var styleAttr, classAttr; var id; if(!ignoreID && SKROLLABLE_ID_DOM_PROPERTY in el) { //We already have this element under control. Grab the corresponding skrollable id. id = el[SKROLLABLE_ID_DOM_PROPERTY]; styleAttr = _skrollables[id].styleAttr; classAttr = _skrollables[id].classAttr; } else { //It's an unknown element. Asign it a new skrollable id. id = (el[SKROLLABLE_ID_DOM_PROPERTY] = _skrollableIdCounter++); styleAttr = el.style.cssText; classAttr = _getClass(el); } _skrollables[id] = { element: el, styleAttr: styleAttr, classAttr: classAttr, anchorTarget: anchorTarget, keyFrames: keyFrames, smoothScrolling: smoothScrollThis, edgeStrategy: edgeStrategy }; _updateClass(el, [SKROLLABLE_CLASS], []); } //Reflow for the first time. _reflow(); //Now that we got all key frame numbers right, actually parse the properties. elementIndex = 0; elementsLength = elements.length; for(; elementIndex < elementsLength; elementIndex++) { var sk = _skrollables[elements[elementIndex][SKROLLABLE_ID_DOM_PROPERTY]]; if(sk === undefined) { continue; } //Parse the property string to objects _parseProps(sk); //Fill key frames with missing properties from left and right _fillProps(sk); } return _instance; }; /** * Transform "relative" mode to "absolute" mode. * That is, calculate anchor position and offset of element. */ Skrollr.prototype.relativeToAbsolute = function(element, viewportAnchor, elementAnchor) { var viewportHeight = documentElement.clientHeight; var box = element.getBoundingClientRect(); var absolute = box.top; //#100: IE doesn't supply "height" with getBoundingClientRect. var boxHeight = box.bottom - box.top; if(viewportAnchor === ANCHOR_BOTTOM) { absolute -= viewportHeight; } else if(viewportAnchor === ANCHOR_CENTER) { absolute -= viewportHeight / 2; } if(elementAnchor === ANCHOR_BOTTOM) { absolute += boxHeight; } else if(elementAnchor === ANCHOR_CENTER) { absolute += boxHeight / 2; } //Compensate scrolling since getBoundingClientRect is relative to viewport. absolute += _instance.getScrollTop(); return (absolute + 0.5) | 0; }; /** * Animates scroll top to new position. */ Skrollr.prototype.animateTo = function(top, options) { options = options || {}; var now = _now(); var scrollTop = _instance.getScrollTop(); //Setting this to a new value will automatically cause the current animation to stop, if any. _scrollAnimation = { startTop: scrollTop, topDiff: top - scrollTop, targetTop: top, duration: options.duration || DEFAULT_DURATION, startTime: now, endTime: now + (options.duration || DEFAULT_DURATION), easing: easings[options.easing || DEFAULT_EASING], done: options.done }; //Don't queue the animation if there's nothing to animate. if(!_scrollAnimation.topDiff) { if(_scrollAnimation.done) { _scrollAnimation.done.call(_instance, false); } _scrollAnimation = undefined; } return _instance; }; /** * Stops animateTo animation. */ Skrollr.prototype.stopAnimateTo = function() { if(_scrollAnimation && _scrollAnimation.done) { _scrollAnimation.done.call(_instance, true); } _scrollAnimation = undefined; }; /** * Returns if an animation caused by animateTo is currently running. */ Skrollr.prototype.isAnimatingTo = function() { return !!_scrollAnimation; }; Skrollr.prototype.setScrollTop = function(top, force) { //Don't do smooth scrolling (last top === new top). if(force === true) { _lastTop = top; _forceRender = true; } if(_isMobile) { _mobileOffset = Math.min(Math.max(top, 0), _maxKeyFrame); } else { window.scrollTo(0, top); } return _instance; }; Skrollr.prototype.getScrollTop = function() { if(_isMobile) { return _mobileOffset; } else { return window.pageYOffset || documentElement.scrollTop || body.scrollTop || 0; } }; Skrollr.prototype.on = function(name, fn) { _listeners[name] = fn; return _instance; }; Skrollr.prototype.off = function(name) { delete _listeners[name]; return _instance; }; Skrollr.prototype.destroy = function() { var cancelAnimFrame = polyfillCAF(); cancelAnimFrame(_animFrame); _removeAllEvents(); _updateClass(documentElement, [NO_SKROLLR_CLASS], [SKROLLR_CLASS, SKROLLR_DESKTOP_CLASS, SKROLLR_MOBILE_CLASS]); var skrollableIndex = 0; var skrollablesLength = _skrollables.length; for(; skrollableIndex < skrollablesLength; skrollableIndex++) { _reset(_skrollables[skrollableIndex].element); } documentElement.style.overflow = body.style.overflow = 'auto'; documentElement.style.height = body.style.height = 'auto'; if(_skrollrBody) { skrollr.setStyle(_skrollrBody, 'transform', 'none'); } _instance = undefined; _skrollrBody = undefined; _listeners = undefined; _forceHeight = undefined; _maxKeyFrame = 0; _scale = 1; _constants = undefined; _mobileDeceleration = undefined; _direction = 'down'; _lastTop = -1; _lastViewportWidth = 0; _lastViewportHeight = 0; _requestReflow = false; _scrollAnimation = undefined; _smoothScrollingEnabled = undefined; _smoothScrollingDuration = undefined; _smoothScrolling = undefined; _forceRender = undefined; _skrollableIdCounter = 0; _edgeStrategy = undefined; _isMobile = false; _mobileOffset = 0; _translateZ = undefined; }; /* Private methods. */ var _initMobile = function() { var initialElement; var initialTouchY; var initialTouchX; var currentTouchY; var currentTouchX; var lastTouchY; var deltaY; var initialTouchTime; var currentTouchTime; var lastTouchTime; var deltaTime; _addEvent(documentElement, [EVENT_TOUCHSTART, EVENT_TOUCHMOVE, EVENT_TOUCHCANCEL, EVENT_TOUCHEND].join(' '), function(e) { e.preventDefault(); var touch = e.changedTouches[0]; currentTouchY = touch.clientY; currentTouchX = touch.clientX; currentTouchTime = e.timeStamp; switch(e.type) { case EVENT_TOUCHSTART: //The last element we tapped on. if(initialElement) { initialElement.blur(); } _instance.stopAnimateTo(); initialElement = e.target; initialTouchY = lastTouchY = currentTouchY; initialTouchX = currentTouchX; initialTouchTime = currentTouchTime; break; case EVENT_TOUCHMOVE: deltaY = currentTouchY - lastTouchY; deltaTime = currentTouchTime - lastTouchTime; _instance.setScrollTop(_mobileOffset - deltaY, true); lastTouchY = currentTouchY; lastTouchTime = currentTouchTime; break; default: case EVENT_TOUCHCANCEL: case EVENT_TOUCHEND: var distanceY = initialTouchY - currentTouchY; var distanceX = initialTouchX - currentTouchX; var distance2 = distanceX * distanceX + distanceY * distanceY; //Check if it was more like a tap (moved less than 7px). if(distance2 < 49) { //It was a tap, click the element. initialElement.focus(); initialElement.click(); return; } initialElement = undefined; var speed = deltaY / deltaTime; //Cap speed at 3 pixel/ms. speed = Math.max(Math.min(speed, 3), -3); var duration = Math.abs(speed / _mobileDeceleration); var targetOffset = speed * duration + 0.5 * _mobileDeceleration * duration * duration; var targetTop = _instance.getScrollTop() - targetOffset; //Relative duration change for when scrolling above bounds. var targetRatio = 0; //Change duration proportionally when scrolling would leave bounds. if(targetTop > _maxKeyFrame) { targetRatio = (_maxKeyFrame - targetTop) / targetOffset; targetTop = _maxKeyFrame; } else if(targetTop < 0) { targetRatio = -targetTop / targetOffset; targetTop = 0; } duration = duration * (1 - targetRatio); _instance.animateTo(targetTop, {easing: 'outCubic', duration: duration}); break; } }); //Just in case there has already been some native scrolling, reset it. window.scrollTo(0, 0); documentElement.style.overflow = body.style.overflow = 'hidden'; }; /** * Updates key frames which depend on others. * That is "end" in "absolute" mode and all key frames in "relative" mode. */ var _updateDependentKeyFrames = function() { var skrollable; var element; var anchorTarget; var keyFrames; var keyFrameIndex; var keyFramesLength; var kf; var skrollableIndex; var skrollablesLength; //First process all relative-mode elements and find the max key frame. skrollableIndex = 0; skrollablesLength = _skrollables.length; for(; skrollableIndex < skrollablesLength; skrollableIndex++) { skrollable = _skrollables[skrollableIndex]; element = skrollable.element; anchorTarget = skrollable.anchorTarget; keyFrames = skrollable.keyFrames; keyFrameIndex = 0; keyFramesLength = keyFrames.length; for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) { kf = keyFrames[keyFrameIndex]; if(kf.mode === 'relative') { _reset(element); kf.frame = _instance.relativeToAbsolute(anchorTarget, kf.anchors[0], kf.anchors[1]) - kf.offset; _reset(element, true); } //Only search for max key frame when forceHeight is enabled. if(_forceHeight) { //Find the max key frame, but don't use one of the data-end ones for comparison. if(!kf.isEnd && kf.frame > _maxKeyFrame) { _maxKeyFrame = kf.frame; } } } } //#133: The document can be larger than the maxKeyFrame we found. _maxKeyFrame = Math.max(_maxKeyFrame, _getDocumentHeight()); //Now process all data-end keyframes. skrollableIndex = 0; skrollablesLength = _skrollables.length; for(; skrollableIndex < skrollablesLength; skrollableIndex++) { skrollable = _skrollables[skrollableIndex]; keyFrames = skrollable.keyFrames; keyFrameIndex = 0; keyFramesLength = keyFrames.length; for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) { kf = keyFrames[keyFrameIndex]; if(kf.isEnd) { kf.frame = _maxKeyFrame - kf.offset; } } skrollable.keyFrames.sort(_keyFrameComparator); } }; /** * Calculates and sets the style properties for the element at the given frame. * @param fakeFrame The frame to render at when smooth scrolling is enabled. * @param actualFrame The actual frame we are at. */ var _calcSteps = function(fakeFrame, actualFrame) { //Iterate over all skrollables. var skrollableIndex = 0; var skrollablesLength = _skrollables.length; for(; skrollableIndex < skrollablesLength; skrollableIndex++) { var skrollable = _skrollables[skrollableIndex]; var element = skrollable.element; var frame = skrollable.smoothScrolling ? fakeFrame : actualFrame; var frames = skrollable.keyFrames; var firstFrame = frames[0].frame; var lastFrame = frames[frames.length - 1].frame; var beforeFirst = frame < firstFrame; var afterLast = frame > lastFrame; var firstOrLastFrame = frames[beforeFirst ? 0 : frames.length - 1]; var key; var value; //If we are before/after the first/last frame, set the styles according to the given edge strategy. if(beforeFirst || afterLast) { //Check if we already handled this edge case last time. //Note: using setScrollTop it's possible that we jumped from one edge to the other. if(beforeFirst && skrollable.edge === -1 || afterLast && skrollable.edge === 1) { continue; } //Add the skrollr-before or -after class. _updateClass(element, [beforeFirst ? SKROLLABLE_BEFORE_CLASS : SKROLLABLE_AFTER_CLASS], [SKROLLABLE_BEFORE_CLASS, SKROLLABLE_BETWEEN_CLASS, SKROLLABLE_AFTER_CLASS]); //Remember that we handled the edge case (before/after the first/last keyframe). skrollable.edge = beforeFirst ? -1 : 1; switch(skrollable.edgeStrategy) { case 'reset': _reset(element); continue; case 'ease': //Handle this case like it would be exactly at first/last keyframe and just pass it on. frame = firstOrLastFrame.frame; break; default: case 'set': var props = firstOrLastFrame.props; for(key in props) { if(hasProp.call(props, key)) { value = _interpolateString(props[key].value); skrollr.setStyle(element, key, value); } } continue; } } else { //Did we handle an edge last time? if(skrollable.edge !== 0) { _updateClass(element, [SKROLLABLE_CLASS, SKROLLABLE_BETWEEN_CLASS], [SKROLLABLE_BEFORE_CLASS, SKROLLABLE_AFTER_CLASS]); skrollable.edge = 0; } } //Find out between which two key frames we are right now. var keyFrameIndex = 0; var framesLength = frames.length - 1; for(; keyFrameIndex < framesLength; keyFrameIndex++) { if(frame >= frames[keyFrameIndex].frame && frame <= frames[keyFrameIndex + 1].frame) { var left = frames[keyFrameIndex]; var right = frames[keyFrameIndex + 1]; for(key in left.props) { if(hasProp.call(left.props, key)) { var progress = (frame - left.frame) / (right.frame - left.frame); //Transform the current progress using the given easing function. progress = left.props[key].easing(progress); //Interpolate between the two values value = _calcInterpolation(left.props[key].value, right.props[key].value, progress); value = _interpolateString(value); skrollr.setStyle(element, key, value); } } break; } } } }; /** * Renders all elements. */ var _render = function() { if(_requestReflow) { _requestReflow = false; _reflow(); } //We may render something else than the actual scrollbar position. var renderTop = _instance.getScrollTop(); //If there's an animation, which ends in current render call, call the callback after rendering. var afterAnimationCallback; var now = _now(); var progress; //Before actually rendering handle the scroll animation, if any. if(_scrollAnimation) { //It's over if(now >= _scrollAnimation.endTime) { renderTop = _scrollAnimation.targetTop; afterAnimationCallback = _scrollAnimation.done; _scrollAnimation = undefined; } else { //Map the current progress to the new progress using given easing function. progress = _scrollAnimation.easing((now - _scrollAnimation.startTime) / _scrollAnimation.duration); renderTop = (_scrollAnimation.startTop + progress * _scrollAnimation.topDiff) | 0; } _instance.setScrollTop(renderTop, true); } //Smooth scrolling only if there's no animation running and if we're not on mobile. else if(!_isMobile) { var smoothScrollingDiff = _smoothScrolling.targetTop - renderTop; //The user scrolled, start new smooth scrolling. if(smoothScrollingDiff) { _smoothScrolling = { startTop: _lastTop, topDiff: renderTop - _lastTop, targetTop: renderTop, startTime: _lastRenderCall, endTime: _lastRenderCall + _smoothScrollingDuration }; } //Interpolate the internal scroll position (not the actual scrollbar). if(now <= _smoothScrolling.endTime) { //Map the current progress to the new progress using easing function. progress = easings.sqrt((now - _smoothScrolling.startTime) / _smoothScrollingDuration); renderTop = (_smoothScrolling.startTop + progress * _smoothScrolling.topDiff) | 0; } } //That's were we actually "scroll" on mobile. if(_isMobile && _skrollrBody) { //Set the transform ("scroll it"). skrollr.setStyle(_skrollrBody, 'transform', 'translate(0, ' + -(_mobileOffset) + 'px) ' + _translateZ); } //Did the scroll position even change? if(_forceRender || _lastTop !== renderTop) { //Remember in which direction are we scrolling? _direction = (renderTop >= _lastTop) ? 'down' : 'up'; _forceRender = false; var listenerParams = { curTop: renderTop, lastTop: _lastTop, maxTop: _maxKeyFrame, direction: _direction }; //Tell the listener we are about to render. var continueRendering = _listeners.beforerender && _listeners.beforerender.call(_instance, listenerParams); //The beforerender listener function is able the cancel rendering. if(continueRendering !== false) { //Now actually interpolate all the styles. _calcSteps(renderTop, _instance.getScrollTop()); //Remember when we last rendered. _lastTop = renderTop; if(_listeners.render) { _listeners.render.call(_instance, listenerParams); } } if(afterAnimationCallback) { afterAnimationCallback.call(_instance, false); } } _lastRenderCall = now; }; /** * Parses the properties for each key frame of the given skrollable. */ var _parseProps = function(skrollable) { //Iterate over all key frames var keyFrameIndex = 0; var keyFramesLength = skrollable.keyFrames.length; for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) { var frame = skrollable.keyFrames[keyFrameIndex]; var easing; var value; var prop; var props = {}; var match; while((match = rxPropValue.exec(frame.props)) !== null) { prop = match[1]; value = match[2]; easing = prop.match(rxPropEasing); //Is there an easing specified for this prop? if(easing !== null) { prop = easing[1]; easing = easing[2]; } else { easing = DEFAULT_EASING; } //Exclamation point at first position forces the value to be taken literal. value = value.indexOf('!') ? _parseProp(value) : [value.slice(1)]; //Save the prop for this key frame with his value and easing function props[prop] = { value: value, easing: easings[easing] }; } frame.props = props; } }; /** * Parses a value extracting numeric values and generating a format string * for later interpolation of the new values in old string. * * @param val The CSS value to be parsed. * @return Something like ["rgba(?%,?%, ?%,?)", 100, 50, 0, .7] * where the first element is the format string later used * and all following elements are the numeric value. */ var _parseProp = function(val) { var numbers = []; //One special case, where floats don't work. //We replace all occurences of rgba colors //which don't use percentage notation with the percentage notation. rxRGBAIntegerColor.lastIndex = 0; val = val.replace(rxRGBAIntegerColor, function(rgba) { return rgba.replace(rxNumericValue, function(n) { return n / 255 * 100 + '%'; }); }); //Handle prefixing of "gradient" values. //For now only the prefixed value will be set. Unprefixed isn't supported anyway. if(theDashedCSSPrefix) { rxGradient.lastIndex = 0; val = val.replace(rxGradient, function(s) { return theDashedCSSPrefix + s; }); } //Now parse ANY number inside this string and create a format string. val = val.replace(rxNumericValue, function(n) { numbers.push(+n); return '{?}'; }); //Add the formatstring as first value. numbers.unshift(val); return numbers; }; /** * Fills the key frames with missing left and right hand properties. * If key frame 1 has property X and key frame 2 is missing X, * but key frame 3 has X again, then we need to assign X to key frame 2 too. * * @param sk A skrollable. */ var _fillProps = function(sk) { //Will collect the properties key frame by key frame var propList = {}; var keyFrameIndex; var keyFramesLength; //Iterate over all key frames from left to right keyFrameIndex = 0; keyFramesLength = sk.keyFrames.length; for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) { _fillPropForFrame(sk.keyFrames[keyFrameIndex], propList); } //Now do the same from right to fill the last gaps propList = {}; //Iterate over all key frames from right to left keyFrameIndex = sk.keyFrames.length - 1; for(; keyFrameIndex >= 0; keyFrameIndex--) { _fillPropForFrame(sk.keyFrames[keyFrameIndex], propList); } }; var _fillPropForFrame = function(frame, propList) { var key; //For each key frame iterate over all right hand properties and assign them, //but only if the current key frame doesn't have the property by itself for(key in propList) { //The current frame misses this property, so assign it. if(!hasProp.call(frame.props, key)) { frame.props[key] = propList[key]; } } //Iterate over all props of the current frame and collect them for(key in frame.props) { propList[key] = frame.props[key]; } }; /** * Calculates the new values for two given values array. */ var _calcInterpolation = function(val1, val2, progress) { var valueIndex; var val1Length = val1.length; //They both need to have the same length if(val1Length !== val2.length) { throw 'Can\'t interpolate between "' + val1[0] + '" and "' + val2[0] + '"'; } //Add the format string as first element. var interpolated = [val1[0]]; valueIndex = 1; for(; valueIndex < val1Length; valueIndex++) { //That's the line where the two numbers are actually interpolated. interpolated[valueIndex] = val1[valueIndex] + ((val2[valueIndex] - val1[valueIndex]) * progress); } return interpolated; }; /** * Interpolates the numeric values into the format string. */ var _interpolateString = function(val) { var valueIndex = 1; rxInterpolateString.lastIndex = 0; return val[0].replace(rxInterpolateString, function() { return val[valueIndex++]; }); }; /** * Resets the class and style attribute to what it was before skrollr manipulated the element. * Also remembers the values it had before reseting, in order to undo the reset. */ var _reset = function(elements, undo) { //We accept a single element or an array of elements. elements = [].concat(elements); var skrollable; var element; var elementsIndex = 0; var elementsLength = elements.length; for(; elementsIndex < elementsLength; elementsIndex++) { element = elements[elementsIndex]; skrollable = _skrollables[element[SKROLLABLE_ID_DOM_PROPERTY]]; //Couldn't find the skrollable for this DOM element. if(!skrollable) { continue; } if(undo) { //Reset class and style to the "dirty" (set by skrollr) values. element.style.cssText = skrollable.dirtyStyleAttr; _updateClass(element, skrollable.dirtyClassAttr); } else { //Remember the "dirty" (set by skrollr) class and style. skrollable.dirtyStyleAttr = element.style.cssText; skrollable.dirtyClassAttr = _getClass(element); //Reset class and style to what it originally was. element.style.cssText = skrollable.styleAttr; _updateClass(element, skrollable.classAttr); } } }; /** * Detects support for 3d transforms by applying it to the skrollr-body. */ var _detect3DTransforms = function() { _translateZ = 'translateZ(0)'; skrollr.setStyle(_skrollrBody, 'transform', _translateZ); var computedStyle = getStyle(_skrollrBody); var computedTransform = computedStyle.getPropertyValue('transform'); var computedTransformWithPrefix = computedStyle.getPropertyValue(theDashedCSSPrefix + 'transform'); var has3D = (computedTransform && computedTransform !== 'none') || (computedTransformWithPrefix && computedTransformWithPrefix !== 'none'); if(!has3D) { _translateZ = ''; } }; /** * Set the CSS property on the given element. Sets prefixed properties as well. */ skrollr.setStyle = function(el, prop, val) { var style = el.style; //Camel case. prop = prop.replace(rxCamelCase, rxCamelCaseFn).replace('-', ''); //Make sure z-index gets a . //This is the only case we need to handle. if(prop === 'zIndex') { //Floor style[prop] = '' + (val | 0); } //#64: "float" can't be set across browsers. Needs to use "cssFloat" for all except IE. else if(prop === 'float') { style.styleFloat = style.cssFloat = val; } else { //Need try-catch for old IE. try { //Set prefixed property if there's a prefix. if(theCSSPrefix) { style[theCSSPrefix + prop.slice(0,1).toUpperCase() + prop.slice(1)] = val; } //Set unprefixed. style[prop] = val; } catch(ignore) {} } }; /** * Cross browser event handling. */ var _addEvent = skrollr.addEvent = function(element, names, callback) { var intermediate = function(e) { //Normalize IE event stuff. e = e || window.event; if(!e.target) { e.target = e.srcElement; } if(!e.preventDefault) { e.preventDefault = function() { e.returnValue = false; }; } return callback.call(this, e); }; names = names.split(' '); var name; var nameCounter = 0; var namesLength = names.length; for(; nameCounter < namesLength; nameCounter++) { name = names[nameCounter]; if(element.addEventListener) { element.addEventListener(name, callback, false); } else { element.attachEvent('on' + name, intermediate); } //Remember the events to be able to flush them later. _registeredEvents.push({ element: element, name: name, listener: callback }); } }; var _removeEvent = skrollr.removeEvent = function(element, names, callback) { names = names.split(' '); var nameCounter = 0; var namesLength = names.length; for(; nameCounter < namesLength; nameCounter++) { if(element.removeEventListener) { element.removeEventListener(names[nameCounter], callback, false); } else { element.detachEvent('on' + names[nameCounter], callback); } } }; var _removeAllEvents = function() { var eventData; var eventCounter = 0; var eventsLength = _registeredEvents.length; for(; eventCounter < eventsLength; eventCounter++) { eventData = _registeredEvents[eventCounter]; _removeEvent(eventData.element, eventData.name, eventData.listener); } _registeredEvents = []; }; var _reflow = function() { var pos = _instance.getScrollTop(); //Will be recalculated by _updateDependentKeyFrames. _maxKeyFrame = 0; if(_forceHeight && !_isMobile) { //un-"force" the height to not mess with the calculations in _updateDependentKeyFrames (#216). body.style.height = 'auto'; } _updateDependentKeyFrames(); if(_forceHeight && !_isMobile) { //"force" the height. body.style.height = (_maxKeyFrame + documentElement.clientHeight) + 'px'; } //The scroll offset may now be larger than needed (on desktop the browser/os prevents scrolling farther than the bottom). if(_isMobile) { _instance.setScrollTop(Math.min(_instance.getScrollTop(), _maxKeyFrame)); } else { //Remember and reset the scroll pos (#217). _instance.setScrollTop(pos, true); } _forceRender = true; }; /* * Returns the height of the document. */ var _getDocumentHeight = function() { var skrollrBodyHeight = (_skrollrBody && _skrollrBody.offsetHeight || 0); var bodyHeight = Math.max(skrollrBodyHeight, body.scrollHeight, body.offsetHeight, documentElement.scrollHeight, documentElement.offsetHeight, documentElement.clientHeight); return bodyHeight - documentElement.clientHeight; }; /** * Returns a string of space separated classnames for the current element. * Works with SVG as well. */ var _getClass = function(element) { var prop = 'className'; //SVG support by using className.baseVal instead of just className. if(window.SVGElement && element instanceof window.SVGElement) { element = element[prop]; prop = 'baseVal'; } return element[prop]; }; /** * Adds and removes a CSS classes. * Works with SVG as well. * add and remove are arrays of strings, * or if remove is ommited add is a string and overwrites all classes. */ var _updateClass = function(element, add, remove) { var prop = 'className'; //SVG support by using className.baseVal instead of just className. if(window.SVGElement && element instanceof window.SVGElement) { element = element[prop]; prop = 'baseVal'; } //When remove is ommited, we want to overwrite/set the classes. if(remove === undefined) { element[prop] = add; return; } //Cache current classes. We will work on a string before passing back to DOM. var val = element[prop]; //All classes to be removed. var classRemoveIndex = 0; var removeLength = remove.length; for(; classRemoveIndex < removeLength; classRemoveIndex++) { val = _untrim(val).replace(_untrim(remove[classRemoveIndex]), ' '); } val = _trim(val); //All classes to be added. var classAddIndex = 0; var addLength = add.length; for(; classAddIndex < addLength; classAddIndex++) { //Only add if el not already has class. if(_untrim(val).indexOf(_untrim(add[classAddIndex])) === -1) { val += ' ' + add[classAddIndex]; } } element[prop] = _trim(val); }; var _trim = function(a) { return a.replace(rxTrim, ''); }; /** * Adds a space before and after the string. */ var _untrim = function(a) { return ' ' + a + ' '; }; var _now = Date.now || function() { return +new Date(); }; var _keyFrameComparator = function(a, b) { return a.frame - b.frame; }; /* * Private variables. */ //Singleton var _instance; /* A list of all elements which should be animated associated with their the metadata. Exmaple skrollable with two key frames animating from 100px width to 20px: skrollable = { element: , styleAttr: ").appendTo("head"),f=b('
').appendTo("html");a=f.height()===3,f.remove(),e.remove()}return a},csstransitions:function(){return!!j}},l;if(e)for(l in k)e.hasOwnProperty(l)||e.addTest(l,k[l]);else{e=a.Modernizr={_version:"1.6ish: miniModernizr for Isotope"};var m=" ",n;for(l in k)n=k[l](),e[l]=n,m+=" "+(n?"":"no-")+l;b("html").addClass(m)}if(e.csstransforms){var o=e.csstransforms3d?{translate:function(a){return"translate3d("+a[0]+"px, "+a[1]+"px, 0) "},scale:function(a){return"scale3d("+a+", "+a+", 1) "}}:{translate:function(a){return"translate("+a[0]+"px, "+a[1]+"px) "},scale:function(a){return"scale("+a+") "}},p=function(a,c,d){var e=b.data(a,"isoTransform")||{},f={},g,h={},j;f[c]=d,b.extend(e,f);for(g in e)j=e[g],h[g]=o[g](j);var k=h.translate||"",l=h.scale||"",m=k+l;b.data(a,"isoTransform",e),a.style[i]=m};b.cssNumber.scale=!0,b.cssHooks.scale={set:function(a,b){p(a,"scale",b)},get:function(a,c){var d=b.data(a,"isoTransform");return d&&d.scale?d.scale:1}},b.fx.step.scale=function(a){b.cssHooks.scale.set(a.elem,a.now+a.unit)},b.cssNumber.translate=!0,b.cssHooks.translate={set:function(a,b){p(a,"translate",b)},get:function(a,c){var d=b.data(a,"isoTransform");return d&&d.translate?d.translate:[0,0]}}}var q,r;e.csstransitions&&(q={WebkitTransitionProperty:"webkitTransitionEnd",MozTransitionProperty:"transitionend",OTransitionProperty:"oTransitionEnd otransitionend",transitionProperty:"transitionend"}[j],r=h("transitionDuration"));var s=b.event,t=b.event.handle?"handle":"dispatch",u;s.special.smartresize={setup:function(){b(this).bind("resize",s.special.smartresize.handler)},teardown:function(){b(this).unbind("resize",s.special.smartresize.handler)},handler:function(a,b){var c=this,d=arguments;a.type="smartresize",u&&clearTimeout(u),u=setTimeout(function(){s[t].apply(c,d)},b==="execAsap"?0:100)}},b.fn.smartresize=function(a){return a?this.bind("smartresize",a):this.trigger("smartresize",["execAsap"])},b.Isotope=function(a,c,d){this.element=b(c),this._create(a),this._init(d)};var v=["width","height"],w=b(a);b.Isotope.settings={resizable:!0,layoutMode:"masonry",containerClass:"isotope",itemClass:"isotope-item",hiddenClass:"isotope-hidden",hiddenStyle:{opacity:0,scale:.001},visibleStyle:{opacity:1,scale:1},containerStyle:{position:"relative",overflow:"hidden"},animationEngine:"best-available",animationOptions:{queue:!1,duration:800},sortBy:"original-order",sortAscending:!0,resizesContainer:!0,transformsEnabled:!0,itemPositionDataEnabled:!1},b.Isotope.prototype={_create:function(a){this.options=b.extend({},b.Isotope.settings,a),this.styleQueue=[],this.elemCount=0;var c=this.element[0].style;this.originalStyle={};var d=v.slice(0);for(var e in this.options.containerStyle)d.push(e);for(var f=0,g=d.length;fg?1:f0&&(i=function(a,b){b.$el[d](b.style,f).one(q,k)},j=!1)}}b.each(this.styleQueue,i),j&&k(),this.styleQueue=[]},resize:function(){this["_"+this.options.layoutMode+"ResizeChanged"]()&&this.reLayout()},reLayout:function(a){this["_"+this.options.layoutMode+"Reset"](),this.layout(this.$filteredAtoms,a)},addItems:function(a,b){var c=this._getAtoms(a);this.$allAtoms=this.$allAtoms.add(c),b&&b(c)},insert:function(a,b){this.element.append(a);var c=this;this.addItems(a,function(a){var d=c._filter(a);c._addHideAppended(d),c._sort(),c.reLayout(),c._revealAppended(d,b)})},appended:function(a,b){var c=this;this.addItems(a,function(a){c._addHideAppended(a),c.layout(a),c._revealAppended(a,b)})},_addHideAppended:function(a){this.$filteredAtoms=this.$filteredAtoms.add(a),a.addClass("no-transition"),this._isInserting=!0,this.styleQueue.push({$el:a,style:this.options.hiddenStyle})},_revealAppended:function(a,b){var c=this;setTimeout(function(){a.removeClass("no-transition"),c.styleQueue.push({$el:a,style:c.options.visibleStyle}),c._isInserting=!1,c._processStyleQueue(a,b)},10)},reloadItems:function(){this.$allAtoms=this._getAtoms(this.element.children())},remove:function(a,b){this.$allAtoms=this.$allAtoms.not(a),this.$filteredAtoms=this.$filteredAtoms.not(a);var c=this,d=function(){a.remove(),b&&b.call(c.element)};a.filter(":not(."+this.options.hiddenClass+")").length?(this.styleQueue.push({$el:a,style:this.options.hiddenStyle}),this._sort(),this.reLayout(d)):d()},shuffle:function(a){this.updateSortData(this.$allAtoms),this.options.sortBy="random",this._sort(),this.reLayout(a)},destroy:function(){var a=this.usingTransforms,b=this.options;this.$allAtoms.removeClass(b.hiddenClass+" "+b.itemClass).each(function(){var b=this.style;b.position="",b.top="",b.left="",b.opacity="",a&&(b[i]="")});var c=this.element[0].style;for(var d in this.originalStyle)c[d]=this.originalStyle[d];this.element.unbind(".isotope").undelegate("."+b.hiddenClass,"click").removeClass(b.containerClass).removeData("isotope"),w.unbind(".isotope")},_getSegments:function(a){var b=this.options.layoutMode,c=a?"rowHeight":"columnWidth",d=a?"height":"width",e=a?"rows":"cols",g=this.element[d](),h,i=this.options[b]&&this.options[b][c]||this.$filteredAtoms["outer"+f(d)](!0)||g;h=Math.floor(g/i),h=Math.max(h,1),this[b][e]=h,this[b][c]=i},_checkIfSegmentsChanged:function(a){var b=this.options.layoutMode,c=a?"rows":"cols",d=this[b][c];return this._getSegments(a),this[b][c]!==d},_masonryReset:function(){this.masonry={},this._getSegments();var a=this.masonry.cols;this.masonry.colYs=[];while(a--)this.masonry.colYs.push(0)},_masonryLayout:function(a){var c=this,d=c.masonry;a.each(function(){var a=b(this),e=Math.ceil(a.outerWidth(!0)/d.columnWidth);e=Math.min(e,d.cols);if(e===1)c._masonryPlaceBrick(a,d.colYs);else{var f=d.cols+1-e,g=[],h,i;for(i=0;id&&(e.x=0,e.y=e.height),c._pushPosition(a,e.x,e.y),e.height=Math.max(e.y+g,e.height),e.x+=f})},_fitRowsGetContainerSize:function(){return{height:this.fitRows.height}},_fitRowsResizeChanged:function(){return!0},_cellsByRowReset:function(){this.cellsByRow={index:0},this._getSegments(),this._getSegments(!0)},_cellsByRowLayout:function(a){var c=this,d=this.cellsByRow;a.each(function(){var a=b(this),e=d.index%d.cols,f=Math.floor(d.index/d.cols),g=(e+.5)*d.columnWidth-a.outerWidth(!0)/2,h=(f+.5)*d.rowHeight-a.outerHeight(!0)/2;c._pushPosition(a,g,h),d.index++})},_cellsByRowGetContainerSize:function(){return{height:Math.ceil(this.$filteredAtoms.length/this.cellsByRow.cols)*this.cellsByRow.rowHeight+this.offset.top}},_cellsByRowResizeChanged:function(){return this._checkIfSegmentsChanged()},_straightDownReset:function(){this.straightDown={y:0}},_straightDownLayout:function(a){var c=this;a.each(function(a){var d=b(this);c._pushPosition(d,0,c.straightDown.y),c.straightDown.y+=d.outerHeight(!0)})},_straightDownGetContainerSize:function(){return{height:this.straightDown.y}},_straightDownResizeChanged:function(){return!0},_masonryHorizontalReset:function(){this.masonryHorizontal={},this._getSegments(!0);var a=this.masonryHorizontal.rows;this.masonryHorizontal.rowXs=[];while(a--)this.masonryHorizontal.rowXs.push(0)},_masonryHorizontalLayout:function(a){var c=this,d=c.masonryHorizontal;a.each(function(){var a=b(this),e=Math.ceil(a.outerHeight(!0)/d.rowHeight);e=Math.min(e,d.rows);if(e===1)c._masonryHorizontalPlaceBrick(a,d.rowXs);else{var f=d.rows+1-e,g=[],h,i;for(i=0;id&&(e.x=e.width,e.y=0),c._pushPosition(a,e.x,e.y),e.width=Math.max(e.x+f,e.width),e.y+=g})},_fitColumnsGetContainerSize:function(){return{width:this.fitColumns.width}},_fitColumnsResizeChanged:function(){return!0},_cellsByColumnReset:function(){this.cellsByColumn={index:0},this._getSegments(),this._getSegments(!0)},_cellsByColumnLayout:function(a){var c=this,d=this.cellsByColumn;a.each(function(){var a=b(this),e=Math.floor(d.index/d.rows),f=d.index%d.rows,g=(e+.5)*d.columnWidth-a.outerWidth(!0)/2,h=(f+.5)*d.rowHeight-a.outerHeight(!0)/2;c._pushPosition(a,g,h),d.index++})},_cellsByColumnGetContainerSize:function(){return{width:Math.ceil(this.$filteredAtoms.length/this.cellsByColumn.rows)*this.cellsByColumn.columnWidth}},_cellsByColumnResizeChanged:function(){return this._checkIfSegmentsChanged(!0)},_straightAcrossReset:function(){this.straightAcross={x:0}},_straightAcrossLayout:function(a){var c=this;a.each(function(a){var d=b(this);c._pushPosition(d,c.straightAcross.x,0),c.straightAcross.x+=d.outerWidth(!0)})},_straightAcrossGetContainerSize:function(){return{width:this.straightAcross.x}},_straightAcrossResizeChanged:function(){return!0}},b.fn.imagesLoaded=function(a){function h(){a.call(c,d)}function i(a){var c=a.target;c.src!==f&&b.inArray(c,g)===-1&&(g.push(c),--e<=0&&(setTimeout(h),d.unbind(".imagesLoaded",i)))}var c=this,d=c.find("img").add(c.filter("img")),e=d.length,f="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",g=[];return e||h(),d.bind("load.imagesLoaded error.imagesLoaded",i).each(function(){var a=this.src;this.src=f,this.src=a}),c};var x=function(b){a.console&&a.console.error(b)};b.fn.isotope=function(a,c){if(typeof a=="string"){var d=Array.prototype.slice.call(arguments,1);this.each(function(){var c=b.data(this,"isotope");if(!c){x("cannot call methods on isotope prior to initialization; attempted to call method '"+a+"'");return}if(!b.isFunction(c[a])||a.charAt(0)==="_"){x("no such method '"+a+"' for isotope instance");return}c[a].apply(c,d)})}else this.each(function(){var d=b.data(this,"isotope");d?(d.option(a),d._init(c)):b.data(this,"isotope",new b.Isotope(a,this,c))});return this}})(window,jQuery); var themetonmgamenu = { build: function(menu){ jQuery(document).ready(function($){ var $main_ul = $(menu + ">ul"); var $main_li = $main_ul.find('ul').parent(); $main_ul.find('>li').each(function(){ jQuery(this).find('>ul').each(function(){ jQuery(this).find('>li').eq(0).append(''); }); }); $main_li.each(function(i){ var $this = $(this); $this.hover( function(){ var $targetul = $(this).children("ul:eq(0)"); var target_width = parseInt($targetul.parent().outerWidth()/2); $targetul.parent().find('.menu_arrow').css({ 'left': target_width+'px' }); if( $targetul.find('.menu_column').length > 0 ){ $targetul.find('>li').addClass('row'); $targetul.find('>li').css({ 'display':'block', 'width':'100%' }); $targetul.find('.menu_column').addClass('col-lg-'+parseInt(12/$targetul.find('.menu_column').length)+' col-md-4 col-xxs-6 col-xs-12'); $targetul.width( $targetul.find('.menu_column').length*230 ); // mega menu set left pos, arrow pos var t_left = parseInt(($targetul.find('.menu_column').length*230-target_width)/2); $targetul.css({ 'left': '-'+t_left+'px' }); $targetul.parent().find('.menu_arrow').css({ 'left': t_left+target_width+'px' }); if( $targetul.parent().hasClass('fullwidth') ){ var wpadin = parseInt(($(window).width() - $('#header > .container').width())/2); var lileft = $targetul.parent().offset().left; $targetul.css({ 'left': '-'+(lileft-wpadin)+'px', 'width': $('#header > .container').width()+'px' }); $targetul.parent().find('.menu_arrow').css({ 'left': parseInt(lileft-wpadin+target_width)+'px' }); } else{ var lileft = parseInt($targetul.parent().offset().left); if( $(window).width() < $targetul.width()/2+lileft ){ var pos_dif = $targetul.width()/2+lileft - $(window).width(); pos_dif = parseInt( pos_dif ); $targetul.css({ 'left': '-'+(parseInt($targetul.width()/2) + pos_dif+target_width)+'px' }); $targetul.parent().find('.menu_arrow').css({ 'left': (parseInt($targetul.width()/2) + pos_dif+target_width+target_width)+'px' }); } } if( $('.wide_menu').length>0 && !$targetul.parent().hasClass('fullwidth') ){ $targetul.css({ 'left': '0px' }); $targetul.parent().find('.menu_arrow').css({ 'left': target_width+'px' }); } } else{ var lileft = parseInt($targetul.parent().offset().left); if( $(window).width() < $targetul.width()+lileft ){ var pos_dif = $targetul.width()/2+lileft - $(window).width(); pos_dif = parseInt( pos_dif ); $targetul.css({ 'left': '-'+(parseInt($targetul.width()/2) + pos_dif+target_width)+'px' }); $targetul.parent().find('.menu_arrow').css({ 'left': (parseInt($targetul.width()/2) + pos_dif+target_width+target_width)+'px' }); $targetul.addClass('floar_right_menu'); } } // calculate Submenu Padding-Top if( $('.wide_menu').length>0 ){ } else{ var sub_top = parseInt(jQuery('#header').css('padding-bottom')) + parseInt((jQuery('#header > .container').outerHeight()-jQuery('.mainmenu').parent().outerHeight())/2+jQuery('.mainmenu').parent().outerHeight()); jQuery('.mainmenu ul.menu > li > ul').css({ 'padding-top': sub_top+'px' }); //var stuck = jQuery('#header').hasClass('stuck'); jQuery(window).scroll(function(){ var sub_top = parseInt(jQuery('#header').css('padding-bottom')) + parseInt((jQuery('#header > .container').outerHeight()-jQuery('.mainmenu').parent().outerHeight())/2+jQuery('.mainmenu').parent().outerHeight()); jQuery('.mainmenu ul.menu > li > ul').css({ 'padding-top': sub_top+'px' }); }); } $targetul.fadeIn('fast'); }, function(){ var $targetul = $(this).children("ul:eq(0)"); $targetul.fadeOut('fast'); } ); }); }); } } themetonmgamenu.build('.mainmenu');/*global jQuery */ /*jshint multistr:true browser:true */ /*! * FitVids 1.0 * * Copyright 2011, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com * Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ * Released under the WTFPL license - http://sam.zoy.org/wtfpl/ * * Date: Thu Sept 01 18:00:00 2011 -0500 */ (function( $ ){ "use strict"; $.fn.fitVids = function( options ) { var settings = { customSelector: null }; if(!document.getElementById('fit-vids-style')) { var div = document.createElement('div'), ref = document.getElementsByTagName('base')[0] || document.getElementsByTagName('script')[0]; div.className = 'fit-vids-style'; div.id = 'fit-vids-style'; div.style.display = 'none'; div.innerHTML = '­'; ref.parentNode.insertBefore(div,ref); } if ( options ) { $.extend( settings, options ); } return this.each(function(){ var selectors = [ "iframe[src*='player.vimeo.com']", "iframe[src*='youtube.com']", "iframe[src*='youtube-nocookie.com']", "iframe[src*='kickstarter.com'][src*='video.html']", "object", "embed" ]; if (settings.customSelector) { selectors.push(settings.customSelector); } var $allVideos = $(this).find(selectors.join(',')); $allVideos = $allVideos.not("object object"); // SwfObj conflict patch $allVideos.each(function(){ var $this = $(this); if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; } var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(), width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(), aspectRatio = height / width; if(!$this.attr('id')){ var videoID = 'fitvid' + Math.floor(Math.random()*999999); $this.attr('id', videoID); } $this.wrap('
').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%"); $this.removeAttr('height').removeAttr('width'); }); }); }; })( jQuery ); function initMobileMenu(){ // Preparing menu for mobile dropdown. var $mobileMenu = ''; var hasMobileMenu = false; if(jQuery('#header').find('#tt-mobile-menu').length) { $mobileMenu = jQuery('#header').find('#tt-mobile-menu').clone().removeClass('hidden-xs hidden-sm hidden-md hidden-lg').hide(); jQuery('#header').find('#tt-mobile-menu').remove(); hasMobileMenu = true; } else if(jQuery('#header').find('.mainmenu').length) { $mobileMenu = jQuery('#header').find('.mainmenu').clone().removeClass('hidden-xs hidden-sm visible-md visible-lg').attr('id','tt-mobile-menu').hide(); $mobileMenu.removeClass('mainmenu metro menu'); hasMobileMenu = true; } else if(jQuery('.wide_menu ').find('.mainmenu').length) { $mobileMenu = jQuery('.wide_menu').find('.mainmenu').clone().removeClass('hidden-xs hidden-sm visible-md visible-lg').attr('id','tt-mobile-menu').hide(); $mobileMenu.removeClass('mainmenu metro menu'); hasMobileMenu = true; } if( jQuery('#one_page_menu').html()!='' && jQuery('#one_page_menu').length>0 ){ $mobileMenu.find('>ul').html( jQuery('#one_page_menu').html() ); } if(hasMobileMenu) { // Adding collapse button of Mobile menu jQuery('#header>.container>.row').append(''); } $mobileMenu.find('ul').attr('style', ''); $mobileMenu.find('li').removeClass('fullwidth megamenu light dark').attr('style', ''); $mobileMenu.children().find('ul').addClass('sub-menu'); $mobileMenu.find('ul.sub-menu').each(function(){ jQuery(this).parent('li').addClass('has-children'); jQuery(this).after(' '); }); $mobileMenu.insertAfter(jQuery('#header')); // Adding expand & collapse event on Plus symbol jQuery('#tt-mobile-menu li.has-children span.collapse').click(function(){ var $this = jQuery(this).closest('.has-children'); $this.siblings('li.tt-open').removeClass('tt-open').children('.sub-menu').slideUp('fast'); $this.toggleClass('tt-open'); if($this.hasClass('tt-open')) { $this.children('.sub-menu').slideDown('fast'); } else { $this.children('.sub-menu').slideUp('fast'); } }); // Adding expand event on links those has subs when click first time jQuery('#tt-mobile-menu .has-children>a').click(function(e){ var $this = jQuery(this).closest('.has-children'); $this.siblings('li.tt-open').removeClass('tt-open').children('.sub-menu').slideUp('fast'); $this.toggleClass('tt-open'); if($this.hasClass('tt-open')){ e.preventDefault(); $this.children('.sub-menu').slideDown('fast'); return false; } }); $mobileMenu.find('li a').click(function(){ if( jQuery('#one_page_menu').html()!='' ){ $this = jQuery(this); $link = $this.attr('href'); $obj = jQuery('div[permalink="'+$link+'"],section[permalink="'+$link+'"]'); if( $obj.length > 0 ){ jQuery('html, body').animate({ scrollTop: $obj.offset().top - jQuery('.sticky-wrapper').height() }, 800); jQuery('#tt-mobile-menu').slideToggle('fast'); return false; } } }); // Show and Hide mobile menu jQuery('a#mobile-menu-expand-collapse').click(function(e){ e.preventDefault(); jQuery('#tt-mobile-menu').slideToggle('fast'); jQuery("html, body").animate({ scrollTop: 0 }, "slow"); }); if( jQuery('#header').hasClass('header_transparent') ){ jQuery('#tt-mobile-menu').css({ 'padding-top': '100px' }); jQuery('#message_bar, #top_Bar').hide(); } } function initMetroBlog(){ jQuery('.metro-loop').isotope({ itemSelector : 'article', filter: '*', getSortData: { number : function($elem){ return parseInt($elem.attr('post-id'), 10); } }, sortBy : 'number', masonry: { columnWidth: 1 } }); jQuery('.metro-loop').find('article').each(function(){ var $current_item = jQuery(this); jQuery(this).find('a').unbind('click') .click(function(){ metro_item_click_hook($current_item.attr('post-id')); return false; }); }); } function metro_item_click_hook($post_id){ jQuery('#metro_item_content').slideUp(); jQuery.post( metro_frontend_ajax, { action: 'get_metro_item_content', post_id: $post_id }, function(data){ if( data != "-1" ){ jQuery('#metro_item_content').html(data); jQuery('#metro_item_content').slideDown(); jQuery('#metro_item_content').find('.close_post_link').unbind('click') .click(function(){ jQuery('#metro_item_content').slideUp(); }); jQuery('#metro_item_content').find('a.prev_post_link').unbind('click') .click(function(){ metro_item_click_hook( jQuery(this).attr('post-id') ); return false; }); jQuery('#metro_item_content').find('a.next_post_link').unbind('click') .click(function(){ metro_item_click_hook( jQuery(this).attr('post-id') ); return false; }); jQuery('html, body').animate({ scrollTop: jQuery("#metro_item_content").offset().top-286+190 }, 800); } else{ console.log(data); } }); } function fix_woo_products(){ jQuery('.products .entry_product .product_image_hover').each(function(){ var $this = jQuery(this); if( $this.find('img').length>0 ){ var wid = parseInt($this.width()*$this.find('img').eq(0).height()/$this.find('img').eq(0).width()); $this.height( wid ); } }); } jQuery(function(){ if(responsive) { initMobileMenu(); } jQuery('.metro_container').isotope({ itemSelector : 'article', filter: '*', getSortData: { number : function($elem){ return parseInt($elem.attr('post-id'), 10); } }, sortBy : 'number', masonry: { columnWidth: 1 } }); /* Checking non sticky option activated */ if(typeof non_sticky_menu != 'undefined' && non_sticky_menu != true) { // menu fixed position if( jQuery('.wide_menu').length > 0 ){ jQuery('.wide_menu').waypoint('sticky', { wrapper: '
' }); } else{ if( jQuery('.icon_menu').length > 0 ){ jQuery('.mainmenu > ul > li > a').css({ 'height' : jQuery('#header').outerHeight()+'px', 'line-height': jQuery('#header').outerHeight()+'px' }); } // check offset var x_offset = 0; if( jQuery('.header_transparent').length>0 ){ x_offset = -30; jQuery('#content #primary, #content #sidebar').css({ 'padding-top': '0px' }); } else if( jQuery('#top_bar').length < 1 || jQuery('#message_bar').length < 1 ){ x_offset = -30; } jQuery('#header').waypoint('sticky', { offset: x_offset, wrapper: '
', handler: function(direction){ if( jQuery('.icon_menu').length > 0 ){ if( direction=='down' ){ jQuery('.mainmenu > ul > li > a').attr('style', ''); } else{ jQuery('.mainmenu > ul > li > a').css({ 'height' : jQuery('#header').outerHeight()+'px', 'line-height': jQuery('#header').outerHeight()+'px' }); } if( jQuery('.header_transparent').length<1 ){ jQuery('.sticky-wrapper').css('height', '77px'); setTimeout(function(){ jQuery('.sticky-wrapper').css('height', jQuery('#header').outerHeight()+'px'); }, 200); } } if( jQuery('.header_transparent').length>0 ){ jQuery('.sticky-wrapper').css('height', '0px'); } } }); } } jQuery('.mainmenu .menu').find('li').each(function(){ var $this = jQuery(this); if( $this.find('ul').length > 0 ){ $this.addClass('page_item_has_children'); } }); jQuery(window).resize(function(){ $sw = 136; $mw = 158; $lw = 188; $metro = jQuery('.metro-loop'); $w = jQuery(window).width(); if( $metro.hasClass('small') ){ $metro.width( parseInt($w/$sw)*$sw ); } else if( $metro.hasClass('medium') ){ $metro.width( parseInt($w/$mw)*$mw ); } else if( $metro.hasClass('large') ){ $metro.width( parseInt($w/$lw)*$lw ); } jQuery('.metro_container').isotope('reLayout'); if( jQuery('.products .entry_product .product_image_hover').length>0 ){ fix_woo_products(); } }); if( jQuery('.products .entry_product .product_image_hover').length>0 ){ jQuery('.products img').load(function(){ fix_woo_products(); }); } /* * Footer layout color filling * 1 => 100% * 2 => 50% + 50% * 3 => 50% + 25% + 25% * 4 => 25% + 25% + 50% * 5 => 33% + 33% + 33% * 6 => 25% + 25% + 25% + 25% */ if(footer == true && footer_layout != 1 && colorful_footer == true) { $footer_block = jQuery('#footer').find('.footer_widget_container'); var actual_height = new Array(); $footer_block.each(function(index){ actual_height.push(jQuery(this).height()); jQuery(this).height(jQuery('#footer').height()-160).css("zIndex", index+10); var colorful = ''; var $colorful = jQuery(colorful).css({ 'position': 'absolute', 'width': '50%', 'height': '100%', 'top': '0', 'z-index': index + 3 }); if(index < 1) jQuery($colorful).css({ 'left': 0 }); else jQuery($colorful).css({ 'right': 0 }); jQuery('#footer > .container').before($colorful); }); /* * Events when Window resize */ jQuery(window).resize(function(){ $color_bg = jQuery('#footer').find('.footer_metro_bg'); // When two columns if(footer_layout == 2) { if (jQuery(window).width() < 768) { $footer_block.each(function(){ jQuery(this).css('height', 'auto'); }); } else { $footer_block.each(function(){ jQuery(this).height(jQuery('#footer').height()-160); }); } } else if(footer_layout == 3) { if (jQuery(window).width() < 768) { $footer_block.each(function(){ jQuery(this).css('height', 'auto'); }); } else if (jQuery(window).width() < 992) { $footer_block.eq(0).css('height', 'auto'); max_height = actual_height[1] > actual_height[2] ? actual_height[1] : actual_height[2]; max_height += 160; $footer_block.eq(1).css('height', max_height); $footer_block.eq(2).css('height', max_height); $color_bg.eq(1).css({ 'height': max_height, 'left': 0, 'bottom':0, 'top' : '' }); $color_bg.eq(2).css({ 'height': max_height, 'right': 0, 'bottom':0, 'top' : '' }); } else { $footer_block.each(function(){ jQuery(this).height(jQuery('#footer').height()-160); }); $color_bg.eq(1).css({'left':'','right':0}); } } else if(footer_layout == 4) { if (jQuery(window).width() < 768) { $footer_block.each(function(){ jQuery(this).css('height', 'auto'); }); } else if (jQuery(window).width() < 992) { $footer_block.eq(2).css('height', 'auto'); max_height = actual_height[0] > actual_height[1] ? actual_height[0] : actual_height[1]; max_height += 160; $footer_block.eq(1).css('height', max_height); $footer_block.eq(0).css('height', max_height); $color_bg.eq(2).css({ 'width': '100%', 'zIndex': 1 }); $color_bg.eq(1).css({ 'height': max_height }); $color_bg.eq(0).css({ 'height': max_height }); } else { $footer_block.each(function(){ jQuery(this).height(jQuery('#footer').height()-160); }); $color_bg.eq(2).css({ 'width': '50%', 'zIndex': 5 }); } } else if(footer_layout == 5) { if (jQuery(window).width() < 992) { $footer_block.each(function(i){ jQuery(this).css('height', 'auto'); var offset = jQuery(this).position(); $color_bg.eq(i).css({ 'height': jQuery(this).height()+160, 'width': '100%', 'top': offset.top }); }); } else { $footer_block.each(function(i){ jQuery(this).height(jQuery('#footer').height()-160); $color_bg.eq(i).css({ 'height': '100%', 'width': '50%', 'top': '' }); }); } } else if(footer_layout == 6) { if (jQuery(window).width() < 768) { $footer_block.each(function(){ jQuery(this).css('height', 'auto'); }); } else if (jQuery(window).width() < 992) { max_height = actual_height[0] > actual_height[1] ? actual_height[0] : actual_height[1]; max_height += 160; $footer_block.eq(0).css('height', max_height); $footer_block.eq(1).css('height', max_height); $color_bg.eq(0).css('height', max_height); $color_bg.eq(1).css('height', max_height); max_height = actual_height[2] > actual_height[3] ? actual_height[2] : actual_height[3]; max_height += 160; $footer_block.eq(2).css('height', max_height); $footer_block.eq(3).css('height', max_height); $color_bg.eq(2).css({ 'height': max_height, 'bottom': 0, 'top': '', 'right': '', 'left': 0 }); $color_bg.eq(3).css({ 'height': max_height, 'bottom': 0, 'top': '' }); } else { $footer_block.each(function(){ jQuery(this).height(jQuery('#footer').height()-160); }); $color_bg.eq(2).css({ 'right': 0, 'left': '', 'height': '100%' }); } } }); jQuery(window).trigger('resize'); } // Video responsive alignment jQuery("section,#footer").not('.ls-wp-container').fitVids(); // init widget child ul li jQuery('.sidebar_area .widget_pages > ul, .sidebar_area .widget_nav_menu > div > ul').each(function(){ var $this = jQuery(this); $this.find('ul').hide(); $this.find('li').hover( function(){ jQuery(this).find('> ul').slideDown('fast'); }, function(){ jQuery(this).find('> ul').slideUp('fast'); } ); }); // Site message button jQuery('#message_bar .icon-remove,#message_bar .icon-times,#message_bar .fa-times').click(function(){ jQuery('#message_bar').slideUp(); set_cookie('message_bar', 'hide'); }); jQuery('a[rel^="prettyPhoto"],a.prettyPhoto,.blox-element.prettyPhoto>a').prettyPhoto({deeplinking:false, social_tools:false}); // Go to top arrow jQuery('span.gototop').click(function() { jQuery('body,html').animate({scrollTop: 0}, 600); }); var s = skrollr.init({ forceHeight: false }); jQuery(window).scroll(function(){ if( jQuery(window).scrollTop() > 500 ){ jQuery('.gototop_footer').addClass('show'); } else{ jQuery('.gototop_footer').removeClass('show'); } }); new jQuery.ajax_search({scope:'.wide_menu'}); jQuery('.add_to_cart_button').click(function(){ var $cart = jQuery('.woocommerce_cart'); var $item = jQuery(this); if($cart.length>0){ setTimeout(function(){ var values = 'action=tt_get_shopping_cart'; jQuery.ajax({ url: metro_frontend_ajax, type: "POST", data:values, success: function(response){ var $response = jQuery('
').append(response); $response.find('#woo_added_cart_msg').remove(); $cart.replaceWith($response.html()); var item_title = $item.parent().parent().find('h3').text(); jQuery('#woo_added_cart_msg').find('.item_name').html(item_title); jQuery('#woo_added_cart_msg').css({ right: '-500px' }); jQuery('#woo_added_cart_msg').show().animate({ right: '0px', opacity: 1 }, 400, function(){ setTimeout(function(){ jQuery('#woo_added_cart_msg').animate({ right:'-500px', opacity: 0 }, 400, function(){ jQuery('#woo_added_cart_msg').hide(); }); }, 2000); }); } }); }, 500); } }); jQuery('.entry_content').each(function(){ var $this = jQuery(this); if( $this.find('>div').length>0 && $this.find('>div').eq(0).hasClass('blox_row_fullwidth') ){ $this.parent().parent().css('padding-top', '0px'); } if( $this.find('>div').length>0 && $this.find('>div').eq($this.find('>div').length-1).hasClass('blox_row_fullwidth') ){ $this.parent().parent().css('padding-bottom', '0px'); } }); jQuery('.entry_media .entry_hover .entry_article_title').each(function(){ var $this = jQuery(this); $this.css({ 'margin-top': -parseInt($this.height()/2) }); }); }); jQuery(window).load(function(){ // fix primary and sidebar heights jQuery('.content').each(function(){ var $this = jQuery(this); if( $this.parent().hasClass('pull-right') ){ $this.parent().attr('prev_class', 'pull-right'); } if( $this.parent().hasClass('pull-left') ){ $this.parent().attr('prev_class', 'pull-left'); } if( jQuery(window).width() < 768 ){ $this.parent().removeClass('pull-right pull-left'); } if( jQuery(this).parent().parent().find('.sidebar_area').length>0 ){ var $sidebar = jQuery(this).parent().parent().find('.sidebar_area'); if( $sidebar.length > 0 && $sidebar.outerHeight() < $this.outerHeight() ){ if( jQuery(window).width() > 768 ){ $sidebar.height( $this.outerHeight()-120 ); } } jQuery(window).resize(function(){ if( jQuery(window).width() < 768 ){ $sidebar.css('height', 'auto'); $this.parent().removeClass('pull-right pull-left'); } else{ $sidebar.height( $this.outerHeight()-120 ); $this.parent().addClass($this.parent().attr('prev_class')); } }); } }); }); function set_cookie(c_name, value, exdays){ exdays = typeof exdays !== 'undefined' ? exdays : 1; var exdate=new Date(); exdate.setDate(exdate.getDate() + exdays); var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString()); document.cookie=c_name + "=" + c_value; } jQuery.ajax_search = function(options){ var defaults = { delay: 300, minChars: 3, scope: 'body' } this.options = jQuery.extend({}, defaults, options); this.scope = jQuery(this.options.scope); this.timer = false; this.lastVal = ""; this.bind_events(); } jQuery.ajax_search.prototype ={ bind_events: function(){ this.scope.on('keyup', '#s' , jQuery.proxy( this.try_search, this)); }, try_search: function(e){ clearTimeout(this.timer); if(e.currentTarget.value.length >= this.options.minChars && this.lastVal != jQuery.trim(e.currentTarget.value)){ this.timer = setTimeout(jQuery.proxy( this.do_search, this, e), this.options.delay); } }, do_search: function(e){ var obj = this, currentField = jQuery(e.currentTarget).attr( "autocomplete", "off" ), form = currentField.parents('form:eq(0)'), results = form.find('.ajax_search_response'), loading = jQuery('
'), action = form.attr('action'), values = form.serialize(); values += '&action=themeton_fajax_search'; if(action.indexOf('?') != -1){ action = action.split('?'); values += "&" + action[1]; } if(!results.length) results = jQuery('
').appendTo(form); if(results.find('.ajax_not_found').length && e.currentTarget.value.indexOf(this.lastVal) != -1) return; this.lastVal = e.currentTarget.value; jQuery.ajax({ url: metro_frontend_ajax, type: "POST", data:values, beforeSend: function() { results.html('').append(loading); }, success: function(response) { if(response == 0) response = ""; results.html(response); }, complete: function() { loading.remove(); } }); } }