'use strict'; var _typeof = typeof symbol === "function" && typeof symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof symbol === "function" && obj.constructor === symbol && obj !== symbol.prototype ? "symbol" : typeof obj; }; /*! canvi - v1.0.0 - 2017-7-20 * canvi is a simple, but customizable, responsive off-canvas navigation. * github repo link * by adam laki / pine */ var canvi = ''; (function () { /* * canvi constructor */ canvi = function canvi() { 'use strict'; /* * set the defaults */ // global element references var pushcontent = '', body = document.queryselector('body'), content = '', options = {}, defaults = {}, openbutton = '', overlay = '', navbar = '', transitionevent = _whichtransitionevent(), isopen = false; // default values defaults = { content: '.canvi-content', isdebug: false, navbar: '.canvi-navbar', speed: '0.3s', openbutton: '.canvi-open-button', position: 'left', pushcontent: true, width: '300px' // create our options from the defaults and the given values from the constructor };if (arguments[0] && _typeof(arguments[0]) === "object") { options = _extenddefaults(defaults, arguments[0]); } // select default elements from the options openbutton = document.queryselector(options.openbutton); navbar = document.queryselector(options.navbar); content = document.queryselector(options.content); /* * call the init of canvi and start the fun */ initcanvi(); function initcanvi() { if (options.isdebug) console.log('%c %s', 'color: #e01a51; font-style: italic;', 'canvi: init is running...'); if (options.isdebug) _objectlog(); _buildmarkup(); _initializemainevents(); // trigger custom event _triggercanvievent('canvi.init'); navbar.setattribute('inert', ''); navbar.setattribute('aria-hidden', 'true'); } /******************************** * public methods ********************************/ /* * open of canvi function */ function opencanvi() { if (options.isdebug) console.log('%c %s', 'color: #e01a51; font-style: italic;', 'canvi: open is running...'); // trigger custom event _triggercanvievent('canvi.before-open'); _buildoverlay(); _setzindex(); // add open classes content.classlist.add('is-canvi-open'); body.classlist.add('is-canvi-open'); navbar.classlist.add('is-canvi-open'); _responsivewidth(); if (options.pushcontent === true) { content.addeventlistener(transitionevent, _transtionopenend); } else { navbar.addeventlistener(transitionevent, _transtionopenend); } navbar.removeattribute('inert'); navbar.removeattribute('aria-hidden'); isopen = true; } /* * close of canvi function */ function closecanvi() { if (options.isdebug) console.log('%c %s', 'color: #e01a51; font-style: italic;', 'canvi: close is running...'); if (isopen === true) { // trigger custom event _triggercanvievent('canvi.before-close'); overlay.classlist.add('canvi-animate-out'); // remove open classes content.style.transform = 'translatex(0)'; body.classlist.remove('is-canvi-open'); navbar.classlist.remove('is-canvi-open'); if (options.pushcontent === true) { content.addeventlistener(transitionevent, _transitioncloseend); } else { navbar.addeventlistener(transitionevent, _transitioncloseend); } navbar.setattribute('inert', ''); navbar.setattribute('aria-hidden', 'true'); isopen = false; } } /* * toggle of canvi function */ function togglecanvi() { if (options.isdebug) console.log('%c %s', 'color: #e01a51; font-style: italic;', 'canvi: toggle is running...'); if (navbar.classlist.contains('is-canvi-open') && content.classlist.contains('is-canvi-open')) { closecanvi(); } else { opencanvi(); } } /******************************** * private methods ********************************/ /* * extend the default markup with some specific values */ function _buildmarkup() { if (options.isdebug) console.log('%c %s', 'color: #ccc; font-style: italic;', 'canvi: build markup...'); // set position value, from options if (options.position) { navbar.setattribute('data-position', options.position); navbar.setattribute('data-push-content', options.pushcontent); } // set the width of the navbar navbar.style.width = options.width; // set ready class to the body body.classlist.add('is-canvi-ready'); } /* * extend the default markup with some specific values */ function _responsivewidth() { if (navbar.classlist.contains('is-canvi-open') && window.matchmedia('(min-width: 0px)').matches) { navbar.style.width = options.width; _responsivewidthhelper(options.width); } if (navbar.classlist.contains('is-canvi-open') && array.isarray(options.responsivewidths) && options.responsivewidths.length > -1) { options.responsivewidths.foreach(function (element) { if (window.matchmedia('(min-width: ' + element.breakpoint + ')').matches) { navbar.style.width = element.width; _responsivewidthhelper(element.width); } }); } } /* * simple helper for the _responsivewidth function */ function _responsivewidthhelper(width) { if (options.pushcontent === true && options.position === 'left') { content.style.transform = 'translatex(' + width + ')'; } if (options.pushcontent === true && options.position === 'right') { content.style.transform = 'translatex(-' + width + ')'; } } /* * build the overlay when the menu is opened */ function _buildoverlay() { if (options.isdebug) console.log('%c %s', 'color: #32da94; font-style: italic;', 'canvi: build overlay...'); // if overlay is true, add if (!content.queryselector('.canvi-overlay')) { overlay = document.createelement('div'); overlay.classname = 'canvi-overlay'; content.appendchild(overlay); } // add close event to the overlay overlay.addeventlistener('click', closecanvi); _settransitionspeed(); } /* * destroy the overlay when the menu is closed */ function _removeoverlay() { if (options.isdebug) console.log('%c %s', 'color: #32da94; font-style: italic;', 'canvi: remove overlay...'); if (options.isdebug) console.log('%c %s', 'color: #999; font-style: italic;', '---------'); // if overlay is true, remove if (overlay) { content.removechild(overlay); // destroy the overlay event overlay.removeeventlistener('click', closecanvi); } } /* * init main events */ function _initializemainevents() { if (options.isdebug) console.log('%c %s', 'color: #ccc; font-style: italic;', 'canvi: init main events...'); if (options.isdebug) console.log('%c %s', 'color: #999; font-style: italic;', '---------'); if (openbutton) { openbutton.addeventlistener('click', opencanvi); } window.addeventlistener('resize', _responsivewidth); } /* * trantions, animation ends */ function _transtionopenend(e) { if (e.propertyname !== 'transform') return; if (options.isdebug) console.log('%c %s', 'color: #ff7600; font-style: italic;', 'canvi: open transition end...'); if (options.isdebug) console.log('%c %s', 'color: #999; font-style: italic;', '---------'); // trigger custom event _triggercanvievent('canvi.after-open'); if (options.pushcontent === true) { content.removeeventlistener(transitionevent, _transtionopenend); } else { navbar.removeeventlistener(transitionevent, _transtionopenend); } } function _transitioncloseend(e) { if (e.propertyname !== 'transform') return; if (options.isdebug) console.log('%c %s', 'color: #ff7600; font-style: italic;', 'canvi: close transition end...'); _triggercanvievent('canvi.after-close'); _removeoverlay(); if (options.pushcontent === true) { content.removeeventlistener(transitionevent, _transitioncloseend); } else { navbar.removeeventlistener(transitionevent, _transitioncloseend); } _resetzindex(); content.classlist.remove('is-canvi-open'); } /* * modify transition speed */ function _settransitionspeed() { navbar.style.transitionduration = options.speed; content.style.transitionduration = options.speed; overlay.style.animationduration = options.speed; } /* * modify z-index values when navigation is pushed */ function _setzindex() { if (options.pushcontent === true) { navbar.style.zindex = 20; content.style.zindex = 40; } else { navbar.style.zindex = 10; content.style.zindex = 5; } } function _resetzindex() { if (options.pushcontent === true) { navbar.style.zindex = 1; content.style.zindex = 5; } else { navbar.style.zindex = 1; content.style.zindex = 5; } } /* * close on keyup */ body.addeventlistener('keyup', function (e) { if (e.keycode == 27) { closecanvi(); } }); /******************************** * utilities ********************************/ /* * extend the defaults with the option */ function _extenddefaults(source, properties) { var property; for (property in properties) { if (properties.hasownproperty(property)) { source[property] = properties[property]; } } return source; } /* * catch transtion end */ function _whichtransitionevent() { var t; var el = document.createelement('fakeelement'); var transitions = { 'transition': 'transitionend', 'otransition': 'otransitionend', 'moztransition': 'transitionend', 'webkittransition': 'webkittransitionend' }; for (t in transitions) { if (el.style[t] !== undefined) { return transitions[t]; } } } /* * custom event helper */ // function _triggercanvievent(name) { // var canvievent = new customevent(name, { // detail: { // navbar: navbar, // openbutton: openbutton, // content: content // } // }); // body.dispatchevent(canvievent); // } function _triggercanvievent(name){ if ( typeof window.customevent === "function" ) return false; function customevent ( event, params ) { params = params || { bubbles: false, cancelable: false, detail: null }; var evt = document.createevent( 'customevent' ); evt.initcustomevent( event, params.bubbles, params.cancelable, params.detail ); return evt; } window.customevent = customevent; } /* * log canvi object */ function _objectlog() { console.groupcollapsed('canvi object'); console.log('open button: ', openbutton); console.log('navbar: ', navbar); console.log('content: ', content); console.groupend(); } /******************************** * return public functions ********************************/ return { open: opencanvi, close: closecanvi, toggle: togglecanvi }; }; })();