From 0d65bc8e98f3b071c047d6aaa7d2ee6aaf82077c Mon Sep 17 00:00:00 2001 From: Theuns Coetzee Date: Sun, 7 Jul 2019 07:15:06 +0200 Subject: [PATCH 01/10] vanilla smooth scroll & sticky --- functions.php | 7 +- header.php | 14 --- js/memberlite-vanilla.js | 234 +++++++++++++++++++++++++++++++++++++++ style.css | 14 +++ 4 files changed, 254 insertions(+), 15 deletions(-) create mode 100644 js/memberlite-vanilla.js diff --git a/functions.php b/functions.php index c7d218b..ca8faa2 100644 --- a/functions.php +++ b/functions.php @@ -20,7 +20,12 @@ function memberlite_init_styles() { wp_enqueue_style( 'memberlite_rtl', get_template_directory_uri() . '/css/rtl.css', array( 'memberlite_style' ), MEMBERLITE_VERSION ); } wp_enqueue_style( 'memberlite_print_style', get_template_directory_uri() . '/css/print.css', array(), MEMBERLITE_VERSION, 'print' ); - wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array( 'jquery' ), MEMBERLITE_VERSION, true ); + + // wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array( 'jquery' ), MEMBERLITE_VERSION, true ); + + // load vanilla js alternative + wp_enqueue_script( 'memberlite-script-vanilla', get_template_directory_uri() . '/js/memberlite-vanilla.js', array( ), MEMBERLITE_VERSION, true ); + wp_enqueue_style( 'font-awesome', get_template_directory_uri() . '/font-awesome/css/all.min.css', array(), '5.8.2' ); // load dark.css for dark/inverted backgrounds diff --git a/header.php b/header.php index b9addba..335cff3 100644 --- a/header.php +++ b/header.php @@ -117,20 +117,6 @@ - diff --git a/js/memberlite-vanilla.js b/js/memberlite-vanilla.js new file mode 100644 index 0000000..878c9e0 --- /dev/null +++ b/js/memberlite-vanilla.js @@ -0,0 +1,234 @@ +/* +* TO DO'S * +// TODO: - scroll to target links in page +// TODO: - sticky navigation +TODO: - switch tab content when clicked +TODO: - check if we should switch tab content on page loads +TODO: - mobile navigation +TODO: Transpile (Babel) +*/ + +// Variables +const anchorLinks = document.querySelectorAll( '[href*="#"]:not([data-toggle="tab"])' ); /* Exclude Memberlite tabs */ +// const memberliteSiteNavigation = document.querySelector('#site-navigation'); +const memberliteSiteNavigation = document.getElementById('site-navigation'); +const memberliteSiteNavigationSticky = document.querySelector('.site-navigation-sticky-wrapper'); + + +// Shared Functions + +function getElementHeight(e) { + if (e != null) { + return e.clientHeight; + } + return 0; +} + +function offsetH(e) { + var rect = e.getBoundingClientRect(), + scrollTop = window.pageYOffset || document.documentElement.scrollTop; + return parseInt(rect.top + scrollTop); +} + +// Custom Scripts from libraries + +/** + * @license + * Lodash (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * Build: `lodash include="throttle"` + */ +;(function(){function t(){}function e(t){return null==t?t===l?d:y:I&&I in Object(t)?n(t):r(t)}function n(t){var e=$.call(t,I),n=t[I];try{t[I]=l;var r=true}catch(t){}var o=_.call(t);return r&&(e?t[I]=n:delete t[I]),o}function r(t){return _.call(t)}function o(t,e,n){function r(e){var n=d,r=g;return d=g=l,x=e,v=t.apply(r,n)}function o(t){return x=t,O=setTimeout(c,e),T?r(t):v}function i(t){var n=t-h,r=t-x,o=e-n;return w?k(o,j-r):o}function f(t){var n=t-h,r=t-x;return h===l||n>=e||n<0||w&&r>=j}function c(){ + var t=D();return f(t)?p(t):(O=setTimeout(c,i(t)),l)}function p(t){return O=l,S&&d?r(t):(d=g=l,v)}function s(){O!==l&&clearTimeout(O),x=0,d=h=g=O=l}function y(){return O===l?v:p(D())}function m(){var t=D(),n=f(t);if(d=arguments,g=this,h=t,n){if(O===l)return o(h);if(w)return O=setTimeout(c,e),r(h)}return O===l&&(O=setTimeout(c,e)),v}var d,g,j,v,O,h,x=0,T=false,w=false,S=true;if(typeof t!="function")throw new TypeError(b);return e=a(e)||0,u(n)&&(T=!!n.leading,w="maxWait"in n,j=w?M(a(n.maxWait)||0,e):j,S="trailing"in n?!!n.trailing:S), + m.cancel=s,m.flush=y,m}function i(t,e,n){var r=true,i=true;if(typeof t!="function")throw new TypeError(b);return u(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),o(t,e,{leading:r,maxWait:e,trailing:i})}function u(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function f(t){return null!=t&&typeof t=="object"}function c(t){return typeof t=="symbol"||f(t)&&e(t)==m}function a(t){if(typeof t=="number")return t;if(c(t))return s;if(u(t)){var e=typeof t.valueOf=="function"?t.valueOf():t; + t=u(e)?e+"":e}if(typeof t!="string")return 0===t?t:+t;t=t.replace(g,"");var n=v.test(t);return n||O.test(t)?h(t.slice(2),n?2:8):j.test(t)?s:+t}var l,p="4.17.5",b="Expected a function",s=NaN,y="[object Null]",m="[object Symbol]",d="[object Undefined]",g=/^\s+|\s+$/g,j=/^[-+]0x[0-9a-f]+$/i,v=/^0b[01]+$/i,O=/^0o[0-7]+$/i,h=parseInt,x=typeof global=="object"&&global&&global.Object===Object&&global,T=typeof self=="object"&&self&&self.Object===Object&&self,w=x||T||Function("return this")(),S=typeof exports=="object"&&exports&&!exports.nodeType&&exports,N=S&&typeof module=="object"&&module&&!module.nodeType&&module,E=Object.prototype,$=E.hasOwnProperty,_=E.toString,W=w.Symbol,I=W?W.toStringTag:l,M=Math.max,k=Math.min,D=function(){ + return w.Date.now()};t.debounce=o,t.throttle=i,t.isObject=u,t.isObjectLike=f,t.isSymbol=c,t.now=D,t.toNumber=a,t.VERSION=p,typeof define=="function"&&typeof define.amd=="object"&&define.amd?(w._=t, define(function(){return t})):N?((N.exports=t)._=t,S._=t):w._=t}).call(this); + +// Site-Specific Functions + +function memberliteSmootScroll(elemArray, scrollBounce = 0) { + elemArray.forEach(link => { + link.addEventListener('click', event => { + event.preventDefault(); + let target = document.querySelector(event.target.hash); + target.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + +// Check whether sticky navigation or WP adminbar is active +// and add their height to adjust scroll positions + + scrollBounce = scrollBounce + getElementHeight(document.getElementById('wpadminbar')) + ( (memberliteSiteNavigationSticky != null) ? getElementHeight(memberliteSiteNavigation) : 0); +// Adjust scroll position if required + if (scrollBounce) { + setTimeout(() => { + window.scrollBy({top: -scrollBounce, behavior: 'smooth'}); + scrollBounce = 0; + }, offsetH(target)/6 > 500 ? parseInt(offsetH(target)/6) : 500 ); //adjust time according to length of scroll + } + }); + }); +} + +// Take Action + +memberliteSmootScroll(anchorLinks); + +// Sticky Nav +// Borrowed from Jessica Chan: +// https://github.com/thecodercoder/simple-sticky-header + + +// This function will run a throttled script every 300 ms to minimize resource usage +var memberliteStickyNav = _.throttle(() => { + + // Detect scroll position + let scrollPosition = Math.round(window.scrollY); + + // If we've scrolled 100px, add "sticky" class to the header + if ( scrollPosition > getElementHeight( memberliteSiteNavigation ) ){ + memberliteSiteNavigation.classList.add( 'site-navigation-sticky' ); + } + // If not, remove "sticky" class from header + else { + memberliteSiteNavigation.classList.remove( 'site-navigation-sticky' ); + } +}, 300); + +if (memberliteSiteNavigationSticky != null) { + // Run the checkHeader function every time you scroll + window.addEventListener( 'scroll', memberliteStickyNav ); +} + + + +// skip link focus fix +// borrowed from _s theme: https://git.io/vWdr2 +var isIe = /(trident|msie)/i.test( navigator.userAgent ); + +if ( isIe && document.getElementById && window.addEventListener ) { + window.addEventListener( 'hashchange', function() { + var id = location.hash.substring( 1 ), + element; + + if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { + return; + } + + element = document.getElementById( id ); + + if ( element ) { + if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { + element.tabIndex = -1; + } + + element.focus(); + } + }, false ); +} + +// switch tab content when clicked +// jQuery( '.memberlite_tabbable .memberlite_tabs li a' ).click( +// function(e) { + + // don't want to jump to # + // e.preventDefault(); + + // which tab was clicked + // var tab, tabarea; + // tab = jQuery( this ).attr( 'href' ).replace( /#/, '' ); + // tabarea = jQuery( this ).closest( '.memberlite_tabbable' ); + + // hide all tab panes + /* + tabarea.find( '.memberlite_tab_pane' ).hide(); + tabarea.find( '.memberlite_tab_pane' ).removeClass( 'memberlite_active' ); + + // show the active one + jQuery( '#' + tab ).show(); + jQuery( '#' + tab ).addClass( 'memberlite_active' ); + + // unstyle tabs + tabarea.find( '.memberlite_tabs li' ).removeClass( 'memberlite_active' ); + + // highlight the active one + jQuery( this ).closest( 'li' ).addClass( 'memberlite_active' ); +*/ +// } +// ); + +const memberliteTabAnchors = document.querySelectorAll( '.memberlite_tabbable .memberlite_tabs li a' ); + +if ( memberliteTabAnchors != null ) { + // memberliteTab(memberliteTabAnchors); + memberliteTabAnchors.forEach(link => { + const memberliteTabAnchor = link.getAttribute('data-value') + const memberliteTabName = memberliteTabAnchor.replace( /#/, '' ); + + console.log('link :', link); + console.log('memberliteTabName :', memberliteTabName); + // .replace( /#/, '' ) + // link.addEventListener('click', event => { + // event.preventDefault(); + // // tab = event.getAttibute( 'href' ).replace( /#/, '' ); + // // console.log(tab); + // // tabarea = link.closest( '.memberlite_tabbable' ); + // // console.log(tabarea); + // }); + // link.addEventListener('click', openCity(event, eaVal)); + link.addEventListener('click', function (event, memberliteTabName) { + // body + console.log(memberliteTabName); + let memberliteTabTarget = `#${memberliteTabName}`; + console.log('memberliteTabTarget :', memberliteTabTarget); + }); + + }); +} + + + +function memberliteTabSwitch(evt, memberliteTabName) { + // do code + +} + +function openCity(evt, cityName) { + var i, tabcontent, tablinks; + tabcontent = document.getElementsByClassName('memberlite_tab_content'); + for (i = 0; i < tabcontent.length; i++) { + tabcontent[i].style.display = "none"; + } + tablinks = document.getElementsByClassName("tablinks"); + for (i = 0; i < tablinks.length; i++) { + tablinks[i].className = tablinks[i].className.replace(" active", ""); + } + // document.getElementById(cityName).style.display = "block"; + // evt.currentTarget.className += " active"; +} + +// memberliteSwitchTabs(memberliteTabAnchors); + +// function onTabClick(event) { +// let activeTabs = document.querySelectorAll('.memberlite_active'); +// // console.log(activeTabs); +// // deactivate existing active tab and panel +// // for( let i = 0; i < activeTabs.length; i++) { +// // activeTabs[i].className = activeTabs[i].className.replace('active', ''); +// // } + +// activeTabs.forEach(function(tab) { +// console.log(tab); +// // var elemCurrent = document.getElementById(elemAttr.replace(/#/g, "")); +// // tab.querySelectorAll('a').replace(/#/g, ""); +// tab.className = tab.className.replace('memberlite_active', ''); +// }); + +// // activate new tab and panel +// event.target.parentElement.className += ' memberlite_active'; +// document.getElementById(event.target.href.split('#')[1]).className += ' memberlite_active'; +// } +// // const element = document.getElementById('nav-tab'); +// const element = document.querySelector('.memberlite_tabs'); + +// element.addEventListener('click', onTabClick, false); \ No newline at end of file diff --git a/style.css b/style.css index 974bc5e..fd54c4e 100644 --- a/style.css +++ b/style.css @@ -72,6 +72,13 @@ html { font-size: 62.5%; /* Corrects text resizing oddly in IE6/7 when body font-size is set using em units http://clagnut.com/blog/348/#c790 */ -webkit-text-size-adjust: 100%; /* Prevents iOS text size adjust after orientation change, without disabling user zoom */ } +/* Check if browser supports */ +@supports (scroll-behavior: smooth) { + html { + /* Modern replacement for javascript smooth scrolling */ + /* scroll-behavior: smooth; */ + } +} *, *:before, *:after { /* apply a natural box layout model to all elements; see http://www.paulirish.com/2012/box-sizing-border-box-ftw/ */ @@ -1235,6 +1242,13 @@ a:active { z-index: 100000; /* Above WP toolbar */ } +/* disable smooth scrolling (set in reset section) for users that have opted in to reduced motion in their browser settings. */ +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } +} + /*-------------------------------------------------------------- 7.0 Alignments --------------------------------------------------------------*/ From 70b17abc83350ee23561a260a29e597151f4578e Mon Sep 17 00:00:00 2001 From: Theuns Coetzee Date: Wed, 10 Jul 2019 07:05:53 +0200 Subject: [PATCH 02/10] replace jQuery with Vanilla JS --- functions.php | 5 +- js/memberlite-vanilla.js | 234 ------------------------ js/memberlite.js | 381 +++++++++++++++++++++++++++------------ js/memberlite_jq.js | 115 ++++++++++++ 4 files changed, 384 insertions(+), 351 deletions(-) delete mode 100644 js/memberlite-vanilla.js create mode 100644 js/memberlite_jq.js diff --git a/functions.php b/functions.php index ca8faa2..c626ec8 100644 --- a/functions.php +++ b/functions.php @@ -21,10 +21,7 @@ function memberlite_init_styles() { } wp_enqueue_style( 'memberlite_print_style', get_template_directory_uri() . '/css/print.css', array(), MEMBERLITE_VERSION, 'print' ); - // wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array( 'jquery' ), MEMBERLITE_VERSION, true ); - - // load vanilla js alternative - wp_enqueue_script( 'memberlite-script-vanilla', get_template_directory_uri() . '/js/memberlite-vanilla.js', array( ), MEMBERLITE_VERSION, true ); + wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array( 'jquery' ), MEMBERLITE_VERSION, true ); wp_enqueue_style( 'font-awesome', get_template_directory_uri() . '/font-awesome/css/all.min.css', array(), '5.8.2' ); diff --git a/js/memberlite-vanilla.js b/js/memberlite-vanilla.js deleted file mode 100644 index 878c9e0..0000000 --- a/js/memberlite-vanilla.js +++ /dev/null @@ -1,234 +0,0 @@ -/* -* TO DO'S * -// TODO: - scroll to target links in page -// TODO: - sticky navigation -TODO: - switch tab content when clicked -TODO: - check if we should switch tab content on page loads -TODO: - mobile navigation -TODO: Transpile (Babel) -*/ - -// Variables -const anchorLinks = document.querySelectorAll( '[href*="#"]:not([data-toggle="tab"])' ); /* Exclude Memberlite tabs */ -// const memberliteSiteNavigation = document.querySelector('#site-navigation'); -const memberliteSiteNavigation = document.getElementById('site-navigation'); -const memberliteSiteNavigationSticky = document.querySelector('.site-navigation-sticky-wrapper'); - - -// Shared Functions - -function getElementHeight(e) { - if (e != null) { - return e.clientHeight; - } - return 0; -} - -function offsetH(e) { - var rect = e.getBoundingClientRect(), - scrollTop = window.pageYOffset || document.documentElement.scrollTop; - return parseInt(rect.top + scrollTop); -} - -// Custom Scripts from libraries - -/** - * @license - * Lodash (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE - * Build: `lodash include="throttle"` - */ -;(function(){function t(){}function e(t){return null==t?t===l?d:y:I&&I in Object(t)?n(t):r(t)}function n(t){var e=$.call(t,I),n=t[I];try{t[I]=l;var r=true}catch(t){}var o=_.call(t);return r&&(e?t[I]=n:delete t[I]),o}function r(t){return _.call(t)}function o(t,e,n){function r(e){var n=d,r=g;return d=g=l,x=e,v=t.apply(r,n)}function o(t){return x=t,O=setTimeout(c,e),T?r(t):v}function i(t){var n=t-h,r=t-x,o=e-n;return w?k(o,j-r):o}function f(t){var n=t-h,r=t-x;return h===l||n>=e||n<0||w&&r>=j}function c(){ - var t=D();return f(t)?p(t):(O=setTimeout(c,i(t)),l)}function p(t){return O=l,S&&d?r(t):(d=g=l,v)}function s(){O!==l&&clearTimeout(O),x=0,d=h=g=O=l}function y(){return O===l?v:p(D())}function m(){var t=D(),n=f(t);if(d=arguments,g=this,h=t,n){if(O===l)return o(h);if(w)return O=setTimeout(c,e),r(h)}return O===l&&(O=setTimeout(c,e)),v}var d,g,j,v,O,h,x=0,T=false,w=false,S=true;if(typeof t!="function")throw new TypeError(b);return e=a(e)||0,u(n)&&(T=!!n.leading,w="maxWait"in n,j=w?M(a(n.maxWait)||0,e):j,S="trailing"in n?!!n.trailing:S), - m.cancel=s,m.flush=y,m}function i(t,e,n){var r=true,i=true;if(typeof t!="function")throw new TypeError(b);return u(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),o(t,e,{leading:r,maxWait:e,trailing:i})}function u(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function f(t){return null!=t&&typeof t=="object"}function c(t){return typeof t=="symbol"||f(t)&&e(t)==m}function a(t){if(typeof t=="number")return t;if(c(t))return s;if(u(t)){var e=typeof t.valueOf=="function"?t.valueOf():t; - t=u(e)?e+"":e}if(typeof t!="string")return 0===t?t:+t;t=t.replace(g,"");var n=v.test(t);return n||O.test(t)?h(t.slice(2),n?2:8):j.test(t)?s:+t}var l,p="4.17.5",b="Expected a function",s=NaN,y="[object Null]",m="[object Symbol]",d="[object Undefined]",g=/^\s+|\s+$/g,j=/^[-+]0x[0-9a-f]+$/i,v=/^0b[01]+$/i,O=/^0o[0-7]+$/i,h=parseInt,x=typeof global=="object"&&global&&global.Object===Object&&global,T=typeof self=="object"&&self&&self.Object===Object&&self,w=x||T||Function("return this")(),S=typeof exports=="object"&&exports&&!exports.nodeType&&exports,N=S&&typeof module=="object"&&module&&!module.nodeType&&module,E=Object.prototype,$=E.hasOwnProperty,_=E.toString,W=w.Symbol,I=W?W.toStringTag:l,M=Math.max,k=Math.min,D=function(){ - return w.Date.now()};t.debounce=o,t.throttle=i,t.isObject=u,t.isObjectLike=f,t.isSymbol=c,t.now=D,t.toNumber=a,t.VERSION=p,typeof define=="function"&&typeof define.amd=="object"&&define.amd?(w._=t, define(function(){return t})):N?((N.exports=t)._=t,S._=t):w._=t}).call(this); - -// Site-Specific Functions - -function memberliteSmootScroll(elemArray, scrollBounce = 0) { - elemArray.forEach(link => { - link.addEventListener('click', event => { - event.preventDefault(); - let target = document.querySelector(event.target.hash); - target.scrollIntoView({ - behavior: 'smooth', - block: 'start' - }); - -// Check whether sticky navigation or WP adminbar is active -// and add their height to adjust scroll positions - - scrollBounce = scrollBounce + getElementHeight(document.getElementById('wpadminbar')) + ( (memberliteSiteNavigationSticky != null) ? getElementHeight(memberliteSiteNavigation) : 0); -// Adjust scroll position if required - if (scrollBounce) { - setTimeout(() => { - window.scrollBy({top: -scrollBounce, behavior: 'smooth'}); - scrollBounce = 0; - }, offsetH(target)/6 > 500 ? parseInt(offsetH(target)/6) : 500 ); //adjust time according to length of scroll - } - }); - }); -} - -// Take Action - -memberliteSmootScroll(anchorLinks); - -// Sticky Nav -// Borrowed from Jessica Chan: -// https://github.com/thecodercoder/simple-sticky-header - - -// This function will run a throttled script every 300 ms to minimize resource usage -var memberliteStickyNav = _.throttle(() => { - - // Detect scroll position - let scrollPosition = Math.round(window.scrollY); - - // If we've scrolled 100px, add "sticky" class to the header - if ( scrollPosition > getElementHeight( memberliteSiteNavigation ) ){ - memberliteSiteNavigation.classList.add( 'site-navigation-sticky' ); - } - // If not, remove "sticky" class from header - else { - memberliteSiteNavigation.classList.remove( 'site-navigation-sticky' ); - } -}, 300); - -if (memberliteSiteNavigationSticky != null) { - // Run the checkHeader function every time you scroll - window.addEventListener( 'scroll', memberliteStickyNav ); -} - - - -// skip link focus fix -// borrowed from _s theme: https://git.io/vWdr2 -var isIe = /(trident|msie)/i.test( navigator.userAgent ); - -if ( isIe && document.getElementById && window.addEventListener ) { - window.addEventListener( 'hashchange', function() { - var id = location.hash.substring( 1 ), - element; - - if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { - return; - } - - element = document.getElementById( id ); - - if ( element ) { - if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { - element.tabIndex = -1; - } - - element.focus(); - } - }, false ); -} - -// switch tab content when clicked -// jQuery( '.memberlite_tabbable .memberlite_tabs li a' ).click( -// function(e) { - - // don't want to jump to # - // e.preventDefault(); - - // which tab was clicked - // var tab, tabarea; - // tab = jQuery( this ).attr( 'href' ).replace( /#/, '' ); - // tabarea = jQuery( this ).closest( '.memberlite_tabbable' ); - - // hide all tab panes - /* - tabarea.find( '.memberlite_tab_pane' ).hide(); - tabarea.find( '.memberlite_tab_pane' ).removeClass( 'memberlite_active' ); - - // show the active one - jQuery( '#' + tab ).show(); - jQuery( '#' + tab ).addClass( 'memberlite_active' ); - - // unstyle tabs - tabarea.find( '.memberlite_tabs li' ).removeClass( 'memberlite_active' ); - - // highlight the active one - jQuery( this ).closest( 'li' ).addClass( 'memberlite_active' ); -*/ -// } -// ); - -const memberliteTabAnchors = document.querySelectorAll( '.memberlite_tabbable .memberlite_tabs li a' ); - -if ( memberliteTabAnchors != null ) { - // memberliteTab(memberliteTabAnchors); - memberliteTabAnchors.forEach(link => { - const memberliteTabAnchor = link.getAttribute('data-value') - const memberliteTabName = memberliteTabAnchor.replace( /#/, '' ); - - console.log('link :', link); - console.log('memberliteTabName :', memberliteTabName); - // .replace( /#/, '' ) - // link.addEventListener('click', event => { - // event.preventDefault(); - // // tab = event.getAttibute( 'href' ).replace( /#/, '' ); - // // console.log(tab); - // // tabarea = link.closest( '.memberlite_tabbable' ); - // // console.log(tabarea); - // }); - // link.addEventListener('click', openCity(event, eaVal)); - link.addEventListener('click', function (event, memberliteTabName) { - // body - console.log(memberliteTabName); - let memberliteTabTarget = `#${memberliteTabName}`; - console.log('memberliteTabTarget :', memberliteTabTarget); - }); - - }); -} - - - -function memberliteTabSwitch(evt, memberliteTabName) { - // do code - -} - -function openCity(evt, cityName) { - var i, tabcontent, tablinks; - tabcontent = document.getElementsByClassName('memberlite_tab_content'); - for (i = 0; i < tabcontent.length; i++) { - tabcontent[i].style.display = "none"; - } - tablinks = document.getElementsByClassName("tablinks"); - for (i = 0; i < tablinks.length; i++) { - tablinks[i].className = tablinks[i].className.replace(" active", ""); - } - // document.getElementById(cityName).style.display = "block"; - // evt.currentTarget.className += " active"; -} - -// memberliteSwitchTabs(memberliteTabAnchors); - -// function onTabClick(event) { -// let activeTabs = document.querySelectorAll('.memberlite_active'); -// // console.log(activeTabs); -// // deactivate existing active tab and panel -// // for( let i = 0; i < activeTabs.length; i++) { -// // activeTabs[i].className = activeTabs[i].className.replace('active', ''); -// // } - -// activeTabs.forEach(function(tab) { -// console.log(tab); -// // var elemCurrent = document.getElementById(elemAttr.replace(/#/g, "")); -// // tab.querySelectorAll('a').replace(/#/g, ""); -// tab.className = tab.className.replace('memberlite_active', ''); -// }); - -// // activate new tab and panel -// event.target.parentElement.className += ' memberlite_active'; -// document.getElementById(event.target.href.split('#')[1]).className += ' memberlite_active'; -// } -// // const element = document.getElementById('nav-tab'); -// const element = document.querySelector('.memberlite_tabs'); - -// element.addEventListener('click', onTabClick, false); \ No newline at end of file diff --git a/js/memberlite.js b/js/memberlite.js index 36a078c..b1cca2a 100644 --- a/js/memberlite.js +++ b/js/memberlite.js @@ -1,115 +1,270 @@ +/* +* TO DO'S * +// TODO: - scroll to target links in page +// TODO: - sticky navigation +// TODO: - switch tab content when clicked +// TODO: - check if we should switch tab content on page loads +TODO: - mobile navigation +TODO: Transpile (Babel) +*??? Only load polyfills if Edge or IE and >= 9 +*??? Polyfills in own file, maybe PHP browser detect and enqueue when IE/Safari +*/ + +// *** Polyfills *** + +// Before +// https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/before#polyfill +(function (arr) { + arr.forEach(function (item) { + if (item.hasOwnProperty('before')) { + return; + } + Object.defineProperty(item, 'before', { + configurable: true, + enumerable: true, + writable: true, + value: function before() { + var argArr = Array.prototype.slice.call(arguments), + docFrag = document.createDocumentFragment(); + + argArr.forEach(function (argItem) { + var isNode = argItem instanceof Node; + docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); + }); + + this.parentNode.insertBefore(docFrag, this); + } + }); + }); +})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); + +// After +// https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/after#Polyfill +(function (arr) { + arr.forEach(function (item) { + if (item.hasOwnProperty('after')) { + return; + } + Object.defineProperty(item, 'after', { + configurable: true, + enumerable: true, + writable: true, + value: function after() { + var argArr = Array.prototype.slice.call(arguments), + docFrag = document.createDocumentFragment(); + + argArr.forEach(function (argItem) { + var isNode = argItem instanceof Node; + docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); + }); + + this.parentNode.insertBefore(docFrag, this.nextSibling); + } + }); + }); +})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); + +// *** Custom Scripts from libraries *** + +// Throttle /** - * memberlite.js + * @license + * Lodash (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * Build: `lodash include="throttle"` */ -jQuery( document ).ready( - function() { - - // scroll to target links in page - jQuery( 'a[href*="#"]:not(.memberlite_tabs a)' ).on( - 'click', function(event) { - - var target = jQuery( '#' + jQuery( this ).attr( 'href' ).hash ); - - if ( target.length ) { - event.preventDefault(); - jQuery( 'html, body' ).animate( - { - scrollTop: target.offset().top - }, 800 - ); - } - } - ); - - // switch tab content when clicked - jQuery( '.memberlite_tabbable .memberlite_tabs li a' ).click( - function(e) { - - // don't want to jump to # - e.preventDefault(); - - // which tab was clicked - var tab, tabarea; - tab = jQuery( this ).attr( 'href' ).replace( /#/, '' ); - tabarea = jQuery( this ).closest( '.memberlite_tabbable' ); - - // hide all tab panes - tabarea.find( '.memberlite_tab_pane' ).hide(); - tabarea.find( '.memberlite_tab_pane' ).removeClass( 'memberlite_active' ); - - // show the active one - jQuery( '#' + tab ).show(); - jQuery( '#' + tab ).addClass( 'memberlite_active' ); - - // unstyle tabs - tabarea.find( '.memberlite_tabs li' ).removeClass( 'memberlite_active' ); - - // highlight the active one - jQuery( this ).closest( 'li' ).addClass( 'memberlite_active' ); - - } - ); - - // check if we should switch tab content on page loads - jQuery( 'a[data-toggle="tab"][href="' + window.location.hash + '"]' ).click(); - - // mobile navigation - var mobilenav_trigger = jQuery( 'button.menu-toggle' ); - jQuery( '#mobile-navigation' ).after( jQuery( '
' ) ); - mobilenav_trigger.click( - function() { - - jQuery( '#mobile-navigation' ).toggleClass( 'toggled' ); - - if (jQuery( '#mobile-navigation' ).hasClass( 'toggled' )) { - jQuery( '#mobile-navigation' ).animate( - { - left: '0px' - } - ); - jQuery( '#mobile-navigation-height-col' ).animate( - { - left: '0px' - } - ); - } else { - jQuery( '#mobile-navigation' ).animate( - { - left: '-100%' - } - ); - jQuery( '#mobile-navigation-height-col' ).animate( - { - left: '-100%' - } - ); - } - } - ); - - // skip link focus fix - // borrowed from _s theme: https://git.io/vWdr2 - var isIe = /(trident|msie)/i.test( navigator.userAgent ); - - if ( isIe && document.getElementById && window.addEventListener ) { - window.addEventListener( 'hashchange', function() { - var id = location.hash.substring( 1 ), - element; - - if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { - return; - } - - element = document.getElementById( id ); - - if ( element ) { - if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { - element.tabIndex = -1; - } - - element.focus(); - } - }, false ); - } - } -); +;(function(){function t(){}function e(t){return null==t?t===l?d:y:I&&I in Object(t)?n(t):r(t)}function n(t){var e=$.call(t,I),n=t[I];try{t[I]=l;var r=true}catch(t){}var o=_.call(t);return r&&(e?t[I]=n:delete t[I]),o}function r(t){return _.call(t)}function o(t,e,n){function r(e){var n=d,r=g;return d=g=l,x=e,v=t.apply(r,n)}function o(t){return x=t,O=setTimeout(c,e),T?r(t):v}function i(t){var n=t-h,r=t-x,o=e-n;return w?k(o,j-r):o}function f(t){var n=t-h,r=t-x;return h===l||n>=e||n<0||w&&r>=j}function c(){ + var t=D();return f(t)?p(t):(O=setTimeout(c,i(t)),l)}function p(t){return O=l,S&&d?r(t):(d=g=l,v)}function s(){O!==l&&clearTimeout(O),x=0,d=h=g=O=l}function y(){return O===l?v:p(D())}function m(){var t=D(),n=f(t);if(d=arguments,g=this,h=t,n){if(O===l)return o(h);if(w)return O=setTimeout(c,e),r(h)}return O===l&&(O=setTimeout(c,e)),v}var d,g,j,v,O,h,x=0,T=false,w=false,S=true;if(typeof t!="function")throw new TypeError(b);return e=a(e)||0,u(n)&&(T=!!n.leading,w="maxWait"in n,j=w?M(a(n.maxWait)||0,e):j,S="trailing"in n?!!n.trailing:S), + m.cancel=s,m.flush=y,m}function i(t,e,n){var r=true,i=true;if(typeof t!="function")throw new TypeError(b);return u(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),o(t,e,{leading:r,maxWait:e,trailing:i})}function u(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function f(t){return null!=t&&typeof t=="object"}function c(t){return typeof t=="symbol"||f(t)&&e(t)==m}function a(t){if(typeof t=="number")return t;if(c(t))return s;if(u(t)){var e=typeof t.valueOf=="function"?t.valueOf():t; + t=u(e)?e+"":e}if(typeof t!="string")return 0===t?t:+t;t=t.replace(g,"");var n=v.test(t);return n||O.test(t)?h(t.slice(2),n?2:8):j.test(t)?s:+t}var l,p="4.17.5",b="Expected a function",s=NaN,y="[object Null]",m="[object Symbol]",d="[object Undefined]",g=/^\s+|\s+$/g,j=/^[-+]0x[0-9a-f]+$/i,v=/^0b[01]+$/i,O=/^0o[0-7]+$/i,h=parseInt,x=typeof global=="object"&&global&&global.Object===Object&&global,T=typeof self=="object"&&self&&self.Object===Object&&self,w=x||T||Function("return this")(),S=typeof exports=="object"&&exports&&!exports.nodeType&&exports,N=S&&typeof module=="object"&&module&&!module.nodeType&&module,E=Object.prototype,$=E.hasOwnProperty,_=E.toString,W=w.Symbol,I=W?W.toStringTag:l,M=Math.max,k=Math.min,D=function(){ + return w.Date.now()};t.debounce=o,t.throttle=i,t.isObject=u,t.isObjectLike=f,t.isSymbol=c,t.now=D,t.toNumber=a,t.VERSION=p,typeof define=="function"&&typeof define.amd=="object"&&define.amd?(w._=t, define(function(){return t})):N?((N.exports=t)._=t,S._=t):w._=t}).call(this); + + +// *** Variables **** +const anchorLinks = document.querySelectorAll( '[href*="#"]:not([data-toggle="tab"])' ); /* Exclude Memberlite tabs */ +const memberliteSiteNavigation = document.getElementById('site-navigation'); +const memberliteSiteNavigationSticky = document.querySelector('.site-navigation-sticky-wrapper'); + +// *** Shared Functions **** + +function getElementHeight(e) { + if (e != null) { + return e.clientHeight; + } + return 0; +} + +function offsetH(e) { + var rect = e.getBoundingClientRect(), + scrollTop = window.pageYOffset || document.documentElement.scrollTop; + return parseInt(rect.top + scrollTop); +} + +// Borrowed from Chris Ferdinandi +// https://gomakethings.com/how-to-simulate-a-click-event-with-javascript/ +// Vanilla JS click() method will not initiate navigation on an element + +/** + * Simulate a click event. + * @public + * @param {Element} elem the element to simulate a click on + */ +var simulateClick = function (elem) { + // Create our event (with options) + var evt = new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window + }); + // If cancelled, don't dispatch our event + var canceled = !elem.dispatchEvent(evt); +}; + +// *** Site-Specific Functions *** + +// scroll to target links in page +function memberliteSmootScroll(elemArray, scrollBounce = 0) { + elemArray.forEach(link => { + link.addEventListener('click', event => { + event.preventDefault(); + let target = document.querySelector(event.target.hash); + target.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + +// Check whether sticky navigation or WP adminbar is active +// and add their height to adjust scroll positions + + scrollBounce = scrollBounce + getElementHeight(document.getElementById('wpadminbar')) + ( (memberliteSiteNavigationSticky != null) ? getElementHeight(memberliteSiteNavigation) : 0); +// Adjust scroll position if required + if (scrollBounce) { + setTimeout(() => { + window.scrollBy({top: -scrollBounce, behavior: 'smooth'}); + scrollBounce = 0; + }, offsetH(target)/6 > 500 ? parseInt(offsetH(target)/6) : 500 ); //adjust time according to length of scroll + } + }); + }); +} +// Take Action +memberliteSmootScroll(anchorLinks); + +// Sticky Nav - replaces inline script previously in header.php +// Borrowed from Jessica Chan: +// https://github.com/thecodercoder/simple-sticky-header + +// This function will run a throttled script every 300 ms to minimize resource usage +var memberliteStickyNav = _.throttle(() => { + + // Detect scroll position + let scrollPosition = Math.round(window.scrollY); + + // If we've scrolled 100px, add "sticky" class to the header + if ( scrollPosition > getElementHeight( memberliteSiteNavigation ) ){ + memberliteSiteNavigation.classList.add( 'site-navigation-sticky' ); + } + // If not, remove "sticky" class from header + else { + memberliteSiteNavigation.classList.remove( 'site-navigation-sticky' ); + } +}, 300); + +if (memberliteSiteNavigationSticky != null) { + // Run the checkHeader function every time you scroll + window.addEventListener( 'scroll', memberliteStickyNav ); +} + +// switch tab content when clicked +const memberliteTabAnchors = document.querySelectorAll( '.memberlite_tabbable .memberlite_tabs li a' ); +if ( memberliteTabAnchors != null ) { + + memberliteTabAnchors.forEach(link => { + + const memberliteTabAnchor = link.getAttribute('href'); + + link.addEventListener('click', function (event, memberliteTabAnchor) { + + event.preventDefault(); + const memberliteTabName = this.getAttribute('href').replace( /#/, '' ); + const memberliteTabArea = this.closest( '.memberlite_tabbable' ); + const memberliteTabPanes = memberliteTabArea.querySelectorAll('.memberlite_tab_pane'); + + for (let index = 0; index < memberliteTabPanes.length; index++) { + memberliteTabPanes[index].style.display = 'none'; + memberliteTabPanes[index].classList.remove('memberlite-active'); + } + + let memberliteTabPaneActive = document.getElementById(memberliteTabName); + memberliteTabPaneActive.style.display = 'block'; + memberliteTabPaneActive.classList.add('memberlite_active'); + + const memberliteTabAreaListItems = memberliteTabArea.querySelectorAll( '.memberlite_tabs li' ); + for (let index = 0; index < memberliteTabAreaListItems.length; index++) { + memberliteTabAreaListItems[index].classList.remove('memberlite_active'); + } + this.closest('li').classList.add( 'memberlite_active' ); + }); + }); +} + +function memberliteTabSwitch(anchor) { + +} + +/* +TODO: see if possible to monitor with haschange to trigger again if location changes. +*/ +// Get value with hashtag (#): (#VideoTutorial) +const urlHash = location.hash; +// console.log('hash :', hash == ''); +if ( urlHash != null && urlHash != '' ) { + memberliteTabHash = document.querySelector( 'a[data-toggle="tab"][href="' + urlHash + '"]' ); + simulateClick(memberliteTabHash); +} + +// mobile navigation +const mobilenav_trigger = document.querySelector( 'button.menu-toggle' ), + mobilenav = document.getElementById( 'mobile-navigation' ); +const mobilenavDiv = document.createElement( 'div' ); +mobilenavDiv.setAttribute( 'id', 'mobile-navigation-height-col' ); +mobilenav.after(mobilenavDiv); +mobilenav_trigger.addEventListener( 'click', function (event) { + mobilenav.classList.toggle( 'toggled' ); + if (mobilenav.classList.contains( 'toggled' )) { + mobilenav.style.left = '0px'; + mobilenav.style.transition = '0.35s'; + mobilenavDiv.style.left = '0px'; + mobilenavDiv.style.transition = '0.35s'; + } else { + mobilenav.style.left = '-100%'; + mobilenav.style.transition = '0.35s'; + mobilenavDiv.style.left = '-100%'; + mobilenavDiv.style.transition = '0.35s'; + } +}); + +// skip link focus fix +// borrowed from _s theme: https://git.io/vWdr2 + +var isIe = /(trident|msie)/i.test( navigator.userAgent ); + +if ( isIe && document.getElementById && window.addEventListener ) { + window.addEventListener( 'hashchange', function() { + var id = location.hash.substring( 1 ), + element; + + if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { + return; + } + + element = document.getElementById( id ); + + if ( element ) { + if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { + element.tabIndex = -1; + } + + element.focus(); + } + }, false ); +} diff --git a/js/memberlite_jq.js b/js/memberlite_jq.js new file mode 100644 index 0000000..36a078c --- /dev/null +++ b/js/memberlite_jq.js @@ -0,0 +1,115 @@ +/** + * memberlite.js + */ +jQuery( document ).ready( + function() { + + // scroll to target links in page + jQuery( 'a[href*="#"]:not(.memberlite_tabs a)' ).on( + 'click', function(event) { + + var target = jQuery( '#' + jQuery( this ).attr( 'href' ).hash ); + + if ( target.length ) { + event.preventDefault(); + jQuery( 'html, body' ).animate( + { + scrollTop: target.offset().top + }, 800 + ); + } + } + ); + + // switch tab content when clicked + jQuery( '.memberlite_tabbable .memberlite_tabs li a' ).click( + function(e) { + + // don't want to jump to # + e.preventDefault(); + + // which tab was clicked + var tab, tabarea; + tab = jQuery( this ).attr( 'href' ).replace( /#/, '' ); + tabarea = jQuery( this ).closest( '.memberlite_tabbable' ); + + // hide all tab panes + tabarea.find( '.memberlite_tab_pane' ).hide(); + tabarea.find( '.memberlite_tab_pane' ).removeClass( 'memberlite_active' ); + + // show the active one + jQuery( '#' + tab ).show(); + jQuery( '#' + tab ).addClass( 'memberlite_active' ); + + // unstyle tabs + tabarea.find( '.memberlite_tabs li' ).removeClass( 'memberlite_active' ); + + // highlight the active one + jQuery( this ).closest( 'li' ).addClass( 'memberlite_active' ); + + } + ); + + // check if we should switch tab content on page loads + jQuery( 'a[data-toggle="tab"][href="' + window.location.hash + '"]' ).click(); + + // mobile navigation + var mobilenav_trigger = jQuery( 'button.menu-toggle' ); + jQuery( '#mobile-navigation' ).after( jQuery( '
' ) ); + mobilenav_trigger.click( + function() { + + jQuery( '#mobile-navigation' ).toggleClass( 'toggled' ); + + if (jQuery( '#mobile-navigation' ).hasClass( 'toggled' )) { + jQuery( '#mobile-navigation' ).animate( + { + left: '0px' + } + ); + jQuery( '#mobile-navigation-height-col' ).animate( + { + left: '0px' + } + ); + } else { + jQuery( '#mobile-navigation' ).animate( + { + left: '-100%' + } + ); + jQuery( '#mobile-navigation-height-col' ).animate( + { + left: '-100%' + } + ); + } + } + ); + + // skip link focus fix + // borrowed from _s theme: https://git.io/vWdr2 + var isIe = /(trident|msie)/i.test( navigator.userAgent ); + + if ( isIe && document.getElementById && window.addEventListener ) { + window.addEventListener( 'hashchange', function() { + var id = location.hash.substring( 1 ), + element; + + if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { + return; + } + + element = document.getElementById( id ); + + if ( element ) { + if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { + element.tabIndex = -1; + } + + element.focus(); + } + }, false ); + } + } +); From c66d15b84dfb5e20712d2b47721dcbe6f8c88f44 Mon Sep 17 00:00:00 2001 From: Theuns Coetzee Date: Wed, 10 Jul 2019 07:16:05 +0200 Subject: [PATCH 03/10] Add polyfill for closest --- js/memberlite.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/js/memberlite.js b/js/memberlite.js index b1cca2a..bce5d70 100644 --- a/js/memberlite.js +++ b/js/memberlite.js @@ -12,6 +12,24 @@ TODO: Transpile (Babel) // *** Polyfills *** +// Closest +if (!Element.prototype.matches) { + Element.prototype.matches = Element.prototype.msMatchesSelector || + Element.prototype.webkitMatchesSelector; +} + +if (!Element.prototype.closest) { + Element.prototype.closest = function(s) { + var el = this; + + do { + if (el.matches(s)) return el; + el = el.parentElement || el.parentNode; + } while (el !== null && el.nodeType === 1); + return null; + }; +} + // Before // https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/before#polyfill (function (arr) { From 66727c0f1948d7566c85f3fe895b1760f36e12fe Mon Sep 17 00:00:00 2001 From: Theuns Coetzee Date: Wed, 10 Jul 2019 07:58:54 +0200 Subject: [PATCH 04/10] replace polyfills with service from polyfill.io --- functions.php | 7 ++++- js/memberlite.js | 82 +++++------------------------------------------- 2 files changed, 14 insertions(+), 75 deletions(-) diff --git a/functions.php b/functions.php index c626ec8..d4f890d 100644 --- a/functions.php +++ b/functions.php @@ -21,7 +21,12 @@ function memberlite_init_styles() { } wp_enqueue_style( 'memberlite_print_style', get_template_directory_uri() . '/css/print.css', array(), MEMBERLITE_VERSION, 'print' ); - wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array( 'jquery' ), MEMBERLITE_VERSION, true ); + if ( ! wp_script_is( 'polyfill-io' ) ) { + wp_register_script( 'polyfill-io', 'https://polyfill.io/v3/polyfill.min.js', array(), '3', false ); + wp_enqueue_script( 'polyfill-io' ); + } + + wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array(), MEMBERLITE_VERSION, true ); wp_enqueue_style( 'font-awesome', get_template_directory_uri() . '/font-awesome/css/all.min.css', array(), '5.8.2' ); diff --git a/js/memberlite.js b/js/memberlite.js index bce5d70..18722aa 100644 --- a/js/memberlite.js +++ b/js/memberlite.js @@ -4,83 +4,17 @@ // TODO: - sticky navigation // TODO: - switch tab content when clicked // TODO: - check if we should switch tab content on page loads -TODO: - mobile navigation -TODO: Transpile (Babel) -*??? Only load polyfills if Edge or IE and >= 9 -*??? Polyfills in own file, maybe PHP browser detect and enqueue when IE/Safari +// TODO: - mobile navigation +// TODO: Transpile (Babel) +TODO: Minify JS +// *??? Only load polyfills if Edge or IE and >= 9 +// *??? Polyfills in own file, maybe PHP browser detect and enqueue when IE/Safari +* Replaced polyfills with polyfill service, thus no need to transpile */ // *** Polyfills *** - -// Closest -if (!Element.prototype.matches) { - Element.prototype.matches = Element.prototype.msMatchesSelector || - Element.prototype.webkitMatchesSelector; -} - -if (!Element.prototype.closest) { - Element.prototype.closest = function(s) { - var el = this; - - do { - if (el.matches(s)) return el; - el = el.parentElement || el.parentNode; - } while (el !== null && el.nodeType === 1); - return null; - }; -} - -// Before -// https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/before#polyfill -(function (arr) { - arr.forEach(function (item) { - if (item.hasOwnProperty('before')) { - return; - } - Object.defineProperty(item, 'before', { - configurable: true, - enumerable: true, - writable: true, - value: function before() { - var argArr = Array.prototype.slice.call(arguments), - docFrag = document.createDocumentFragment(); - - argArr.forEach(function (argItem) { - var isNode = argItem instanceof Node; - docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); - }); - - this.parentNode.insertBefore(docFrag, this); - } - }); - }); -})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); - -// After -// https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/after#Polyfill -(function (arr) { - arr.forEach(function (item) { - if (item.hasOwnProperty('after')) { - return; - } - Object.defineProperty(item, 'after', { - configurable: true, - enumerable: true, - writable: true, - value: function after() { - var argArr = Array.prototype.slice.call(arguments), - docFrag = document.createDocumentFragment(); - - argArr.forEach(function (argItem) { - var isNode = argItem instanceof Node; - docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); - }); - - this.parentNode.insertBefore(docFrag, this.nextSibling); - } - }); - }); -})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); +// https://polyfill.io +// Only loads polyfills the current user's browser needs. // *** Custom Scripts from libraries *** From 30600ae2c612ba7021ffe7f13c5d1271296b257a Mon Sep 17 00:00:00 2001 From: Theuns Coetzee Date: Wed, 10 Jul 2019 08:35:19 +0200 Subject: [PATCH 05/10] compress and switch to minified js --- functions.php | 2 +- js/memberlite.js | 4 +++- js/memberlite.min.js | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 js/memberlite.min.js diff --git a/functions.php b/functions.php index d4f890d..23adc54 100644 --- a/functions.php +++ b/functions.php @@ -26,7 +26,7 @@ function memberlite_init_styles() { wp_enqueue_script( 'polyfill-io' ); } - wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array(), MEMBERLITE_VERSION, true ); + wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.min.js', array(), MEMBERLITE_VERSION, true ); wp_enqueue_style( 'font-awesome', get_template_directory_uri() . '/font-awesome/css/all.min.css', array(), '5.8.2' ); diff --git a/js/memberlite.js b/js/memberlite.js index 18722aa..f72b8d4 100644 --- a/js/memberlite.js +++ b/js/memberlite.js @@ -6,7 +6,9 @@ // TODO: - check if we should switch tab content on page loads // TODO: - mobile navigation // TODO: Transpile (Babel) -TODO: Minify JS +TODO: Minify JS +? minify 39.56% compression, saving 3.78 kb. +? should we minify or leave open to optimization plugins // *??? Only load polyfills if Edge or IE and >= 9 // *??? Polyfills in own file, maybe PHP browser detect and enqueue when IE/Safari * Replaced polyfills with polyfill service, thus no need to transpile diff --git a/js/memberlite.min.js b/js/memberlite.min.js new file mode 100644 index 0000000..36d2a82 --- /dev/null +++ b/js/memberlite.min.js @@ -0,0 +1 @@ +(function(){function p(){}function q(b){return null==b?b===a?m:c:G&&G in Object(b)?e(b):n(b)}function e(b){var c=C.call(b,G),d=b[G];try{b[G]=a;var e=!0}catch(a){}var f=E.call(b);return e&&(c?b[G]=d:delete b[G]),f}function n(a){return E.call(a)}function z(b,q,t){function n(c){var d=m,e=z;return m=z=a,F=c,C=b.apply(e,d)}function r(a){return F=a,D=setTimeout(f,q),G?n(a):C}function o(a){var b=a-E,c=a-F,d=q-b;return J?I(d,B-c):d}function i(b){var c=b-E,d=b-F;return E===a||c>=q||0>c||J&&d>=B}function f(){var b=k();return i(b)?c(b):(D=setTimeout(f,o(b)),a)}function c(b){return D=a,K&&m?n(b):(m=z=a,C)}function p(){D!==a&&clearTimeout(D),F=0,m=E=z=D=a}function s(){return D===a?C:c(k())}function y(){var b=k(),c=i(b);if(m=arguments,z=this,E=b,c){if(D===a)return r(E);if(J)return D=setTimeout(f,q),n(E)}return D===a&&(D=setTimeout(f,q)),C}var m,z,B,C,D,E,F=0,G=!1,J=!1,K=!0;if("function"!=typeof b)throw new TypeError(l);return q=u(q)||0,A(t)&&(G=!!t.leading,J="maxWait"in t,B=J?H(u(t.maxWait)||0,q):B,K="trailing"in t?!!t.trailing:K),y.cancel=p,y.flush=s,y}function o(a,b,c){var d=!0,e=!0;if("function"!=typeof a)throw new TypeError(l);return A(c)&&(d="leading"in c?!!c.leading:d,e="trailing"in c?!!c.trailing:e),z(a,b,{leading:d,maxWait:b,trailing:e})}function A(a){var b=typeof a;return null!=a&&("object"==b||"function"==b)}function i(a){return null!=a&&"object"==typeof a}function f(a){return"symbol"==typeof a||i(a)&&q(a)==r}function u(a){if("number"==typeof a)return a;if(f(a))return b;if(A(a)){var c="function"==typeof a.valueOf?a.valueOf():a;a=A(c)?c+"":c}if("string"!=typeof a)return 0===a?a:+a;a=a.replace(d,"");var e=j.test(a);return e||s.test(a)?v(a.slice(2),e?2:8):g.test(a)?b:+a}var a,l="Expected a function",b=NaN,c="[object Null]",r="[object Symbol]",m="[object Undefined]",d=/^\s+|\s+$/g,g=/^[-+]0x[0-9a-f]+$/i,j=/^0b[01]+$/i,s=/^0o[0-7]+$/i,v=parseInt,h="object"==typeof global&&global&&global.Object===Object&&global,t="object"==typeof self&&self&&self.Object===Object&&self,x=h||t||Function("return this")(),w="object"==typeof exports&&exports&&!exports.nodeType&&exports,y=w&&"object"==typeof module&&module&&!module.nodeType&&module,B=Object.prototype,C=B.hasOwnProperty,E=B.toString,F=x.Symbol,G=F?F.toStringTag:a,H=Math.max,I=Math.min,k=function(){return x.Date.now()};p.debounce=z,p.throttle=o,p.isObject=A,p.isObjectLike=i,p.isSymbol=f,p.now=k,p.toNumber=u,p.VERSION="4.17.5","function"==typeof define&&"object"==typeof define.amd&&define.amd?(x._=p,define(function(){return p})):y?((y.exports=p)._=p,w._=p):x._=p}).call(this);const anchorLinks=document.querySelectorAll("[href*=\"#\"]:not([data-toggle=\"tab\"])"),memberliteSiteNavigation=document.getElementById("site-navigation"),memberliteSiteNavigationSticky=document.querySelector(".site-navigation-sticky-wrapper");function getElementHeight(a){return null==a?0:a.clientHeight}function offsetH(a){var b=a.getBoundingClientRect(),c=window.pageYOffset||document.documentElement.scrollTop;return parseInt(b.top+c)}var simulateClick=function(a){var b=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window}),c=!a.dispatchEvent(b)};function memberliteSmootScroll(a,b=0){a.forEach(a=>{a.addEventListener("click",a=>{a.preventDefault();let c=document.querySelector(a.target.hash);c.scrollIntoView({behavior:"smooth",block:"start"}),b=b+getElementHeight(document.getElementById("wpadminbar"))+(null==memberliteSiteNavigationSticky?0:getElementHeight(memberliteSiteNavigation)),b&&setTimeout(()=>{window.scrollBy({top:-b,behavior:"smooth"}),b=0},500{let a=Math.round(window.scrollY);a>getElementHeight(memberliteSiteNavigation)?memberliteSiteNavigation.classList.add("site-navigation-sticky"):memberliteSiteNavigation.classList.remove("site-navigation-sticky")},300);null!=memberliteSiteNavigationSticky&&window.addEventListener("scroll",memberliteStickyNav);const memberliteTabAnchors=document.querySelectorAll(".memberlite_tabbable .memberlite_tabs li a");null!=memberliteTabAnchors&&memberliteTabAnchors.forEach(a=>{a.getAttribute("href");a.addEventListener("click",function(a){a.preventDefault();const b=this.getAttribute("href").replace(/#/,""),c=this.closest(".memberlite_tabbable"),d=c.querySelectorAll(".memberlite_tab_pane");for(let b=0;b Date: Wed, 10 Jul 2019 08:46:27 +0200 Subject: [PATCH 06/10] remove completed TODO's --- js/memberlite.js | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/js/memberlite.js b/js/memberlite.js index f72b8d4..9793c28 100644 --- a/js/memberlite.js +++ b/js/memberlite.js @@ -1,24 +1,4 @@ -/* -* TO DO'S * -// TODO: - scroll to target links in page -// TODO: - sticky navigation -// TODO: - switch tab content when clicked -// TODO: - check if we should switch tab content on page loads -// TODO: - mobile navigation -// TODO: Transpile (Babel) -TODO: Minify JS -? minify 39.56% compression, saving 3.78 kb. -? should we minify or leave open to optimization plugins -// *??? Only load polyfills if Edge or IE and >= 9 -// *??? Polyfills in own file, maybe PHP browser detect and enqueue when IE/Safari -* Replaced polyfills with polyfill service, thus no need to transpile -*/ - -// *** Polyfills *** -// https://polyfill.io -// Only loads polyfills the current user's browser needs. - -// *** Custom Scripts from libraries *** +// *** Custom Scripts from external libraries *** // Throttle /** From c3a8313f46d741232b53ba484eacdbf381d5970a Mon Sep 17 00:00:00 2001 From: Theuns Coetzee Date: Wed, 17 Jul 2019 15:11:28 +0200 Subject: [PATCH 07/10] Fix IE compatibility --- functions.php | 16 +++-- js/memberlite.js | 174 +++++++++++++++++++++++------------------------ 2 files changed, 98 insertions(+), 92 deletions(-) diff --git a/functions.php b/functions.php index 23adc54..722928e 100644 --- a/functions.php +++ b/functions.php @@ -21,12 +21,18 @@ function memberlite_init_styles() { } wp_enqueue_style( 'memberlite_print_style', get_template_directory_uri() . '/css/print.css', array(), MEMBERLITE_VERSION, 'print' ); - if ( ! wp_script_is( 'polyfill-io' ) ) { - wp_register_script( 'polyfill-io', 'https://polyfill.io/v3/polyfill.min.js', array(), '3', false ); - wp_enqueue_script( 'polyfill-io' ); - } + wp_enqueue_script( 'memberlite-polyfills', get_template_directory_uri() . '/js/polyfills.js', array(), MEMBERLITE_VERSION, true ); + wp_script_add_data( 'memberlite-polyfills', 'conditional', 'IE' ); // load polyfills only for IE + + // Internet Explorer HTML5 support + wp_enqueue_script( 'html5shiv', '//cdnjs.com/libraries/html5shiv', array(), '3.7.3', false); + wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' ); + + // Internet Explorer 8 media query support + wp_enqueue_script( 'respond', '//cdnjs.com/libraries/respond.js/', array(), '1.4.2', false); + wp_script_add_data( 'respond', 'conditional', 'lt IE 9' ); - wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.min.js', array(), MEMBERLITE_VERSION, true ); + wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array(), MEMBERLITE_VERSION, true ); wp_enqueue_style( 'font-awesome', get_template_directory_uri() . '/font-awesome/css/all.min.css', array(), '5.8.2' ); diff --git a/js/memberlite.js b/js/memberlite.js index 9793c28..637cadb 100644 --- a/js/memberlite.js +++ b/js/memberlite.js @@ -1,5 +1,4 @@ -// *** Custom Scripts from external libraries *** - +'use strict'; // Throttle /** * @license @@ -7,29 +6,28 @@ * Build: `lodash include="throttle"` */ ;(function(){function t(){}function e(t){return null==t?t===l?d:y:I&&I in Object(t)?n(t):r(t)}function n(t){var e=$.call(t,I),n=t[I];try{t[I]=l;var r=true}catch(t){}var o=_.call(t);return r&&(e?t[I]=n:delete t[I]),o}function r(t){return _.call(t)}function o(t,e,n){function r(e){var n=d,r=g;return d=g=l,x=e,v=t.apply(r,n)}function o(t){return x=t,O=setTimeout(c,e),T?r(t):v}function i(t){var n=t-h,r=t-x,o=e-n;return w?k(o,j-r):o}function f(t){var n=t-h,r=t-x;return h===l||n>=e||n<0||w&&r>=j}function c(){ - var t=D();return f(t)?p(t):(O=setTimeout(c,i(t)),l)}function p(t){return O=l,S&&d?r(t):(d=g=l,v)}function s(){O!==l&&clearTimeout(O),x=0,d=h=g=O=l}function y(){return O===l?v:p(D())}function m(){var t=D(),n=f(t);if(d=arguments,g=this,h=t,n){if(O===l)return o(h);if(w)return O=setTimeout(c,e),r(h)}return O===l&&(O=setTimeout(c,e)),v}var d,g,j,v,O,h,x=0,T=false,w=false,S=true;if(typeof t!="function")throw new TypeError(b);return e=a(e)||0,u(n)&&(T=!!n.leading,w="maxWait"in n,j=w?M(a(n.maxWait)||0,e):j,S="trailing"in n?!!n.trailing:S), - m.cancel=s,m.flush=y,m}function i(t,e,n){var r=true,i=true;if(typeof t!="function")throw new TypeError(b);return u(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),o(t,e,{leading:r,maxWait:e,trailing:i})}function u(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function f(t){return null!=t&&typeof t=="object"}function c(t){return typeof t=="symbol"||f(t)&&e(t)==m}function a(t){if(typeof t=="number")return t;if(c(t))return s;if(u(t)){var e=typeof t.valueOf=="function"?t.valueOf():t; - t=u(e)?e+"":e}if(typeof t!="string")return 0===t?t:+t;t=t.replace(g,"");var n=v.test(t);return n||O.test(t)?h(t.slice(2),n?2:8):j.test(t)?s:+t}var l,p="4.17.5",b="Expected a function",s=NaN,y="[object Null]",m="[object Symbol]",d="[object Undefined]",g=/^\s+|\s+$/g,j=/^[-+]0x[0-9a-f]+$/i,v=/^0b[01]+$/i,O=/^0o[0-7]+$/i,h=parseInt,x=typeof global=="object"&&global&&global.Object===Object&&global,T=typeof self=="object"&&self&&self.Object===Object&&self,w=x||T||Function("return this")(),S=typeof exports=="object"&&exports&&!exports.nodeType&&exports,N=S&&typeof module=="object"&&module&&!module.nodeType&&module,E=Object.prototype,$=E.hasOwnProperty,_=E.toString,W=w.Symbol,I=W?W.toStringTag:l,M=Math.max,k=Math.min,D=function(){ - return w.Date.now()};t.debounce=o,t.throttle=i,t.isObject=u,t.isObjectLike=f,t.isSymbol=c,t.now=D,t.toNumber=a,t.VERSION=p,typeof define=="function"&&typeof define.amd=="object"&&define.amd?(w._=t, define(function(){return t})):N?((N.exports=t)._=t,S._=t):w._=t}).call(this); - + var t=D();return f(t)?p(t):(O=setTimeout(c,i(t)),l)}function p(t){return O=l,S&&d?r(t):(d=g=l,v)}function s(){O!==l&&clearTimeout(O),x=0,d=h=g=O=l}function y(){return O===l?v:p(D())}function m(){var t=D(),n=f(t);if(d=arguments,g=this,h=t,n){if(O===l)return o(h);if(w)return O=setTimeout(c,e),r(h)}return O===l&&(O=setTimeout(c,e)),v}var d,g,j,v,O,h,x=0,T=false,w=false,S=true;if(typeof t!="function")throw new TypeError(b);return e=a(e)||0,u(n)&&(T=!!n.leading,w="maxWait"in n,j=w?M(a(n.maxWait)||0,e):j,S="trailing"in n?!!n.trailing:S), + m.cancel=s,m.flush=y,m}function i(t,e,n){var r=true,i=true;if(typeof t!="function")throw new TypeError(b);return u(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),o(t,e,{leading:r,maxWait:e,trailing:i})}function u(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function f(t){return null!=t&&typeof t=="object"}function c(t){return typeof t=="symbol"||f(t)&&e(t)==m}function a(t){if(typeof t=="number")return t;if(c(t))return s;if(u(t)){var e=typeof t.valueOf=="function"?t.valueOf():t; + t=u(e)?e+"":e}if(typeof t!="string")return 0===t?t:+t;t=t.replace(g,"");var n=v.test(t);return n||O.test(t)?h(t.slice(2),n?2:8):j.test(t)?s:+t}var l,p="4.17.5",b="Expected a function",s=NaN,y="[object Null]",m="[object Symbol]",d="[object Undefined]",g=/^\s+|\s+$/g,j=/^[-+]0x[0-9a-f]+$/i,v=/^0b[01]+$/i,O=/^0o[0-7]+$/i,h=parseInt,x=typeof global=="object"&&global&&global.Object===Object&&global,T=typeof self=="object"&&self&&self.Object===Object&&self,w=x||T||Function("return this")(),S=typeof exports=="object"&&exports&&!exports.nodeType&&exports,N=S&&typeof module=="object"&&module&&!module.nodeType&&module,E=Object.prototype,$=E.hasOwnProperty,_=E.toString,W=w.Symbol,I=W?W.toStringTag:l,M=Math.max,k=Math.min,D=function(){ + return w.Date.now()};t.debounce=o,t.throttle=i,t.isObject=u,t.isObjectLike=f,t.isSymbol=c,t.now=D,t.toNumber=a,t.VERSION=p,typeof define=="function"&&typeof define.amd=="object"&&define.amd?(w._=t, define(function(){return t})):N?((N.exports=t)._=t,S._=t):w._=t}).call(this); // *** Variables **** -const anchorLinks = document.querySelectorAll( '[href*="#"]:not([data-toggle="tab"])' ); /* Exclude Memberlite tabs */ -const memberliteSiteNavigation = document.getElementById('site-navigation'); -const memberliteSiteNavigationSticky = document.querySelector('.site-navigation-sticky-wrapper'); +var anchorLinks = document.querySelectorAll('[href*="#"]:not([data-toggle="tab"])'); /* Exclude Memberlite tabs */ +var memberliteSiteNavigation = document.getElementById('site-navigation'); +var memberliteSiteNavigationSticky = document.querySelector('.site-navigation-sticky-wrapper'); // *** Shared Functions **** function getElementHeight(e) { if (e != null) { return e.clientHeight; - } + } return 0; } function offsetH(e) { var rect = e.getBoundingClientRect(), - scrollTop = window.pageYOffset || document.documentElement.scrollTop; + scrollTop = window.pageYOffset || document.documentElement.scrollTop; return parseInt(rect.top + scrollTop); } @@ -42,40 +40,44 @@ function offsetH(e) { * @public * @param {Element} elem the element to simulate a click on */ -var simulateClick = function (elem) { - // Create our event (with options) - var evt = new MouseEvent('click', { - bubbles: true, - cancelable: true, - view: window - }); - // If cancelled, don't dispatch our event - var canceled = !elem.dispatchEvent(evt); +var simulateClick = function simulateClick(elem) { + // Create our event (with options) + var evt = new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window + }); + // If cancelled, don't dispatch our event + var canceled = !elem.dispatchEvent(evt); }; // *** Site-Specific Functions *** // scroll to target links in page -function memberliteSmootScroll(elemArray, scrollBounce = 0) { - elemArray.forEach(link => { - link.addEventListener('click', event => { +function memberliteSmootScroll(elemArray) { + var scrollBounce = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; + + var elemArrayArray = Array.prototype.slice.call(elemArray); // Convert Nodelist to Array (IE doesn't support nodelist with foreach) + + elemArrayArray.forEach(function (link) { + link.addEventListener('click', function (event) { event.preventDefault(); - let target = document.querySelector(event.target.hash); + var target = document.querySelector(event.target.hash); target.scrollIntoView({ behavior: 'smooth', block: 'start' }); - -// Check whether sticky navigation or WP adminbar is active -// and add their height to adjust scroll positions - scrollBounce = scrollBounce + getElementHeight(document.getElementById('wpadminbar')) + ( (memberliteSiteNavigationSticky != null) ? getElementHeight(memberliteSiteNavigation) : 0); -// Adjust scroll position if required + // Check whether sticky navigation or WP adminbar is active + // and add their height to adjust scroll positions + + scrollBounce = scrollBounce + getElementHeight(document.getElementById('wpadminbar')) + (memberliteSiteNavigationSticky != null ? getElementHeight(memberliteSiteNavigation) : 0); + // Adjust scroll position if required if (scrollBounce) { - setTimeout(() => { - window.scrollBy({top: -scrollBounce, behavior: 'smooth'}); - scrollBounce = 0; - }, offsetH(target)/6 > 500 ? parseInt(offsetH(target)/6) : 500 ); //adjust time according to length of scroll + setTimeout(function () { + window.scrollBy({ top: -scrollBounce, behavior: 'smooth' }); + scrollBounce = 0; + }, offsetH(target) / 6 > 500 ? parseInt(offsetH(target) / 6) : 500); //adjust time according to length of scroll } }); }); @@ -88,83 +90,81 @@ memberliteSmootScroll(anchorLinks); // https://github.com/thecodercoder/simple-sticky-header // This function will run a throttled script every 300 ms to minimize resource usage -var memberliteStickyNav = _.throttle(() => { +var memberliteStickyNav = _.throttle(function () { // Detect scroll position - let scrollPosition = Math.round(window.scrollY); + var scrollPosition = Math.round(window.scrollY); // If we've scrolled 100px, add "sticky" class to the header - if ( scrollPosition > getElementHeight( memberliteSiteNavigation ) ){ - memberliteSiteNavigation.classList.add( 'site-navigation-sticky' ); + if (scrollPosition > getElementHeight(memberliteSiteNavigation)) { + memberliteSiteNavigation.classList.add('site-navigation-sticky'); } // If not, remove "sticky" class from header else { - memberliteSiteNavigation.classList.remove( 'site-navigation-sticky' ); - } + memberliteSiteNavigation.classList.remove('site-navigation-sticky'); + } }, 300); if (memberliteSiteNavigationSticky != null) { // Run the checkHeader function every time you scroll - window.addEventListener( 'scroll', memberliteStickyNav ); + window.addEventListener('scroll', memberliteStickyNav); } // switch tab content when clicked -const memberliteTabAnchors = document.querySelectorAll( '.memberlite_tabbable .memberlite_tabs li a' ); -if ( memberliteTabAnchors != null ) { - - memberliteTabAnchors.forEach(link => { +var memberliteTabAnchors = document.querySelectorAll('.memberlite_tabbable .memberlite_tabs li a'); +if (memberliteTabAnchors != null) { +var memberliteTabAnchorsArray = Array.prototype.slice.call(memberliteTabAnchors); // Convert Nodelist to Array (IE doesn't support nodelist with foreach) + memberliteTabAnchorsArray.forEach(function (link) { - const memberliteTabAnchor = link.getAttribute('href'); + var memberliteTabAnchor = link.getAttribute('href'); - link.addEventListener('click', function (event, memberliteTabAnchor) { + link.addEventListener('click', function (event, memberliteTabAnchor) { - event.preventDefault(); - const memberliteTabName = this.getAttribute('href').replace( /#/, '' ); - const memberliteTabArea = this.closest( '.memberlite_tabbable' ); - const memberliteTabPanes = memberliteTabArea.querySelectorAll('.memberlite_tab_pane'); + event.preventDefault(); + var memberliteTabName = this.getAttribute('href').replace(/#/, ''); + var memberliteTabArea = this.closest('.memberlite_tabbable'); + var memberliteTabPanes = memberliteTabArea.querySelectorAll('.memberlite_tab_pane'); - for (let index = 0; index < memberliteTabPanes.length; index++) { - memberliteTabPanes[index].style.display = 'none'; - memberliteTabPanes[index].classList.remove('memberlite-active'); - } + for (var index = 0; index < memberliteTabPanes.length; index++) { + memberliteTabPanes[index].style.display = 'none'; + memberliteTabPanes[index].classList.remove('memberlite-active'); + } - let memberliteTabPaneActive = document.getElementById(memberliteTabName); - memberliteTabPaneActive.style.display = 'block'; - memberliteTabPaneActive.classList.add('memberlite_active'); + var memberliteTabPaneActive = document.getElementById(memberliteTabName); + memberliteTabPaneActive.style.display = 'block'; + memberliteTabPaneActive.classList.add('memberlite_active'); - const memberliteTabAreaListItems = memberliteTabArea.querySelectorAll( '.memberlite_tabs li' ); - for (let index = 0; index < memberliteTabAreaListItems.length; index++) { - memberliteTabAreaListItems[index].classList.remove('memberlite_active'); - } - this.closest('li').classList.add( 'memberlite_active' ); + var memberliteTabAreaListItems = memberliteTabArea.querySelectorAll('.memberlite_tabs li'); + for (var _index = 0; _index < memberliteTabAreaListItems.length; _index++) { + memberliteTabAreaListItems[_index].classList.remove('memberlite_active'); + } + this.closest('li').classList.add('memberlite_active'); }); }); } -function memberliteTabSwitch(anchor) { - -} +function memberliteTabSwitch(anchor) {} /* TODO: see if possible to monitor with haschange to trigger again if location changes. */ // Get value with hashtag (#): (#VideoTutorial) -const urlHash = location.hash; +var urlHash = location.hash; // console.log('hash :', hash == ''); -if ( urlHash != null && urlHash != '' ) { - memberliteTabHash = document.querySelector( 'a[data-toggle="tab"][href="' + urlHash + '"]' ); +if (urlHash != null && urlHash != '') { + var memberliteTabHash = document.querySelector('a[data-toggle="tab"][href="' + urlHash + '"]'); simulateClick(memberliteTabHash); } // mobile navigation -const mobilenav_trigger = document.querySelector( 'button.menu-toggle' ), - mobilenav = document.getElementById( 'mobile-navigation' ); -const mobilenavDiv = document.createElement( 'div' ); -mobilenavDiv.setAttribute( 'id', 'mobile-navigation-height-col' ); +var mobilenav_trigger = document.querySelector('button.menu-toggle'), + mobilenav = document.getElementById('mobile-navigation'); +var mobilenavDiv = document.createElement('div'); +mobilenavDiv.setAttribute('id', 'mobile-navigation-height-col'); mobilenav.after(mobilenavDiv); -mobilenav_trigger.addEventListener( 'click', function (event) { - mobilenav.classList.toggle( 'toggled' ); - if (mobilenav.classList.contains( 'toggled' )) { +mobilenav_trigger.addEventListener('click', function (event) { + mobilenav.classList.toggle('toggled'); + if (mobilenav.classList.contains('toggled')) { mobilenav.style.left = '0px'; mobilenav.style.transition = '0.35s'; mobilenavDiv.style.left = '0px'; @@ -180,25 +180,25 @@ mobilenav_trigger.addEventListener( 'click', function (event) { // skip link focus fix // borrowed from _s theme: https://git.io/vWdr2 -var isIe = /(trident|msie)/i.test( navigator.userAgent ); +var isIe = /(trident|msie)/i.test(navigator.userAgent); -if ( isIe && document.getElementById && window.addEventListener ) { - window.addEventListener( 'hashchange', function() { - var id = location.hash.substring( 1 ), - element; +if (isIe && document.getElementById && window.addEventListener) { + window.addEventListener('hashchange', function () { + var id = location.hash.substring(1), + element; - if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { + if (!/^[A-z0-9_-]+$/.test(id)) { return; } - element = document.getElementById( id ); + element = document.getElementById(id); - if ( element ) { - if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { + if (element) { + if (!/^(?:a|select|input|button|textarea)$/i.test(element.tagName)) { element.tabIndex = -1; } element.focus(); } - }, false ); -} + }, false); +} \ No newline at end of file From 065d5cd16b27545a1487fd0bb1c1e7ba12c5fc81 Mon Sep 17 00:00:00 2001 From: Scott Kingsley Clark Date: Wed, 27 Oct 2021 15:57:53 -0500 Subject: [PATCH 08/10] Remove scripts needed for earlier versions of IE no longer supported --- functions.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/functions.php b/functions.php index 722928e..ef9b6a0 100644 --- a/functions.php +++ b/functions.php @@ -21,17 +21,6 @@ function memberlite_init_styles() { } wp_enqueue_style( 'memberlite_print_style', get_template_directory_uri() . '/css/print.css', array(), MEMBERLITE_VERSION, 'print' ); - wp_enqueue_script( 'memberlite-polyfills', get_template_directory_uri() . '/js/polyfills.js', array(), MEMBERLITE_VERSION, true ); - wp_script_add_data( 'memberlite-polyfills', 'conditional', 'IE' ); // load polyfills only for IE - - // Internet Explorer HTML5 support - wp_enqueue_script( 'html5shiv', '//cdnjs.com/libraries/html5shiv', array(), '3.7.3', false); - wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' ); - - // Internet Explorer 8 media query support - wp_enqueue_script( 'respond', '//cdnjs.com/libraries/respond.js/', array(), '1.4.2', false); - wp_script_add_data( 'respond', 'conditional', 'lt IE 9' ); - wp_enqueue_script( 'memberlite-script', get_template_directory_uri() . '/js/memberlite.js', array(), MEMBERLITE_VERSION, true ); wp_enqueue_style( 'font-awesome', get_template_directory_uri() . '/font-awesome/css/all.min.css', array(), '5.8.2' ); From 7d13c1658d8851cc60b625f2382f9b9c6ddbae62 Mon Sep 17 00:00:00 2001 From: Scott Kingsley Clark Date: Wed, 27 Oct 2021 17:17:23 -0500 Subject: [PATCH 09/10] Namespace JS vars --- js/memberlite.js | 299 +++++++++++++++++++++++++---------------------- 1 file changed, 159 insertions(+), 140 deletions(-) diff --git a/js/memberlite.js b/js/memberlite.js index 637cadb..19deb14 100644 --- a/js/memberlite.js +++ b/js/memberlite.js @@ -12,23 +12,25 @@ return w.Date.now()};t.debounce=o,t.throttle=i,t.isObject=u,t.isObjectLike=f,t.isSymbol=c,t.now=D,t.toNumber=a,t.VERSION=p,typeof define=="function"&&typeof define.amd=="object"&&define.amd?(w._=t, define(function(){return t})):N?((N.exports=t)._=t,S._=t):w._=t}).call(this); // *** Variables **** -var anchorLinks = document.querySelectorAll('[href*="#"]:not([data-toggle="tab"])'); /* Exclude Memberlite tabs */ -var memberliteSiteNavigation = document.getElementById('site-navigation'); -var memberliteSiteNavigationSticky = document.querySelector('.site-navigation-sticky-wrapper'); +var memberliteLinks = document.querySelectorAll( '[href*="#"]:not([data-toggle="tab"])' ); /* Exclude Memberlite tabs */ +var memberliteSiteNavigation = document.getElementById( 'site-navigation' ); +var memberliteSiteNavigationSticky = document.querySelector( '.site-navigation-sticky-wrapper' ); // *** Shared Functions **** -function getElementHeight(e) { - if (e != null) { - return e.clientHeight; - } - return 0; +function memberliteGetElementHeight( e ) { + if ( e != null ) { + return e.clientHeight; + } + + return 0; } -function offsetH(e) { - var rect = e.getBoundingClientRect(), - scrollTop = window.pageYOffset || document.documentElement.scrollTop; - return parseInt(rect.top + scrollTop); +function memberliteOffsetH( e ) { + var rect = e.getBoundingClientRect(), + scrollTop = window.pageYOffset || document.documentElement.scrollTop; + + return parseInt( rect.top + scrollTop ); } // Borrowed from Chris Ferdinandi @@ -40,165 +42,182 @@ function offsetH(e) { * @public * @param {Element} elem the element to simulate a click on */ -var simulateClick = function simulateClick(elem) { - // Create our event (with options) - var evt = new MouseEvent('click', { - bubbles: true, - cancelable: true, - view: window - }); - // If cancelled, don't dispatch our event - var canceled = !elem.dispatchEvent(evt); +var memberliteSimulateClick = function ( elem ) { + // Create our event (with options) + var evt = new MouseEvent( 'click', { + bubbles : true, + cancelable : true, + view : window + } ); + + // If cancelled, don't dispatch our event + var canceled = ! elem.dispatchEvent( evt ); }; // *** Site-Specific Functions *** // scroll to target links in page -function memberliteSmootScroll(elemArray) { - var scrollBounce = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; - - var elemArrayArray = Array.prototype.slice.call(elemArray); // Convert Nodelist to Array (IE doesn't support nodelist with foreach) - - elemArrayArray.forEach(function (link) { - link.addEventListener('click', function (event) { - event.preventDefault(); - var target = document.querySelector(event.target.hash); - target.scrollIntoView({ - behavior: 'smooth', - block: 'start' - }); - - // Check whether sticky navigation or WP adminbar is active - // and add their height to adjust scroll positions - - scrollBounce = scrollBounce + getElementHeight(document.getElementById('wpadminbar')) + (memberliteSiteNavigationSticky != null ? getElementHeight(memberliteSiteNavigation) : 0); - // Adjust scroll position if required - if (scrollBounce) { - setTimeout(function () { - window.scrollBy({ top: -scrollBounce, behavior: 'smooth' }); - scrollBounce = 0; - }, offsetH(target) / 6 > 500 ? parseInt(offsetH(target) / 6) : 500); //adjust time according to length of scroll - } - }); - }); +function memberliteSmootScroll( elemArray ) { + var scrollBounce = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; + + var elemArrayArray = Array.prototype.slice.call( elemArray ); // Convert Nodelist to Array (IE doesn't support nodelist with foreach) + + elemArrayArray.forEach( function ( link ) { + link.addEventListener( 'click', function ( event ) { + event.preventDefault(); + + var target = document.querySelector( event.target.hash ); + + target.scrollIntoView( { + behavior : 'smooth', + block : 'start' + } ); + + // Check whether sticky navigation or WP adminbar is active + // and add their height to adjust scroll positions + + scrollBounce = scrollBounce + memberliteGetElementHeight( document.getElementById( 'wpadminbar' ) ) + (memberliteSiteNavigationSticky != null ? memberliteGetElementHeight( memberliteSiteNavigation ) : 0); + + // Adjust scroll position if required + if ( scrollBounce ) { + setTimeout( + function () { + window.scrollBy( {top : -scrollBounce, behavior : 'smooth'} ); + scrollBounce = 0; + }, + memberliteOffsetH( target ) / 6 > 500 ? parseInt( memberliteOffsetH( target ) / 6 ) : 500 //adjust time according to length of scroll + ); + } + } ); + } ); } + // Take Action -memberliteSmootScroll(anchorLinks); +memberliteSmootScroll( memberliteLinks ); // Sticky Nav - replaces inline script previously in header.php -// Borrowed from Jessica Chan: +// Borrowed from Jessica Chan: // https://github.com/thecodercoder/simple-sticky-header // This function will run a throttled script every 300 ms to minimize resource usage -var memberliteStickyNav = _.throttle(function () { - - // Detect scroll position - var scrollPosition = Math.round(window.scrollY); - - // If we've scrolled 100px, add "sticky" class to the header - if (scrollPosition > getElementHeight(memberliteSiteNavigation)) { - memberliteSiteNavigation.classList.add('site-navigation-sticky'); - } - // If not, remove "sticky" class from header - else { - memberliteSiteNavigation.classList.remove('site-navigation-sticky'); - } -}, 300); - -if (memberliteSiteNavigationSticky != null) { - // Run the checkHeader function every time you scroll - window.addEventListener('scroll', memberliteStickyNav); +var memberliteStickyNav = _.throttle( function () { + + // Detect scroll position + var scrollPosition = Math.round( window.scrollY ); + + // If we've scrolled 100px, add "sticky" class to the header + if ( scrollPosition > memberliteGetElementHeight( memberliteSiteNavigation ) ) { + memberliteSiteNavigation.classList.add( 'site-navigation-sticky' ); + } + // If not, remove "sticky" class from header + else { + memberliteSiteNavigation.classList.remove( 'site-navigation-sticky' ); + } +}, 300 ); + +if ( memberliteSiteNavigationSticky != null ) { + // Run the checkHeader function every time you scroll + window.addEventListener( 'scroll', memberliteStickyNav ); } // switch tab content when clicked -var memberliteTabAnchors = document.querySelectorAll('.memberlite_tabbable .memberlite_tabs li a'); -if (memberliteTabAnchors != null) { -var memberliteTabAnchorsArray = Array.prototype.slice.call(memberliteTabAnchors); // Convert Nodelist to Array (IE doesn't support nodelist with foreach) - memberliteTabAnchorsArray.forEach(function (link) { - - var memberliteTabAnchor = link.getAttribute('href'); - - link.addEventListener('click', function (event, memberliteTabAnchor) { - - event.preventDefault(); - var memberliteTabName = this.getAttribute('href').replace(/#/, ''); - var memberliteTabArea = this.closest('.memberlite_tabbable'); - var memberliteTabPanes = memberliteTabArea.querySelectorAll('.memberlite_tab_pane'); - - for (var index = 0; index < memberliteTabPanes.length; index++) { - memberliteTabPanes[index].style.display = 'none'; - memberliteTabPanes[index].classList.remove('memberlite-active'); - } - - var memberliteTabPaneActive = document.getElementById(memberliteTabName); - memberliteTabPaneActive.style.display = 'block'; - memberliteTabPaneActive.classList.add('memberlite_active'); - - var memberliteTabAreaListItems = memberliteTabArea.querySelectorAll('.memberlite_tabs li'); - for (var _index = 0; _index < memberliteTabAreaListItems.length; _index++) { - memberliteTabAreaListItems[_index].classList.remove('memberlite_active'); - } - this.closest('li').classList.add('memberlite_active'); - }); - }); +var memberliteTabAnchors = document.querySelectorAll( '.memberlite_tabbable .memberlite_tabs li a' ); +if ( memberliteTabAnchors != null ) { + // Convert Nodelist to Array (IE doesn't support nodelist with foreach) + var memberliteTabAnchorsArray = Array.prototype.slice.call( memberliteTabAnchors ); + + memberliteTabAnchorsArray.forEach( function ( link ) { + var memberliteTabAnchor = link.getAttribute( 'href' ); + + link.addEventListener( 'click', function ( event, memberliteTabAnchor ) { + event.preventDefault(); + + var memberliteTabName = this.getAttribute( 'href' ).replace( /#/, '' ); + var memberliteTabArea = this.closest( '.memberlite_tabbable' ); + var memberliteTabPanes = memberliteTabArea.querySelectorAll( '.memberlite_tab_pane' ); + + for ( var index = 0; index < memberliteTabPanes.length; index++ ) { + memberliteTabPanes[index].style.display = 'none'; + memberliteTabPanes[index].classList.remove( 'memberlite-active' ); + } + + var memberliteTabPaneActive = document.getElementById( memberliteTabName ); + + memberliteTabPaneActive.style.display = 'block'; + memberliteTabPaneActive.classList.add( 'memberlite_active' ); + + var memberliteTabAreaListItems = memberliteTabArea.querySelectorAll( '.memberlite_tabs li' ); + + for ( var _index = 0; _index < memberliteTabAreaListItems.length; _index++ ) { + memberliteTabAreaListItems[_index].classList.remove( 'memberlite_active' ); + } + + this.closest( 'li' ).classList.add( 'memberlite_active' ); + } ); + } ); } -function memberliteTabSwitch(anchor) {} +function memberliteTabSwitch( anchor ) { +} /* TODO: see if possible to monitor with haschange to trigger again if location changes. */ // Get value with hashtag (#): (#VideoTutorial) -var urlHash = location.hash; -// console.log('hash :', hash == ''); -if (urlHash != null && urlHash != '') { - var memberliteTabHash = document.querySelector('a[data-toggle="tab"][href="' + urlHash + '"]'); - simulateClick(memberliteTabHash); +var memberliteUrlHash = location.hash; + +if ( memberliteUrlHash != null && memberliteUrlHash != '' ) { + var memberliteTabHash = document.querySelector( 'a[data-toggle="tab"][href="' + memberliteUrlHash + '"]' ); + + memberliteSimulateClick( memberliteTabHash ); } // mobile navigation -var mobilenav_trigger = document.querySelector('button.menu-toggle'), - mobilenav = document.getElementById('mobile-navigation'); -var mobilenavDiv = document.createElement('div'); -mobilenavDiv.setAttribute('id', 'mobile-navigation-height-col'); -mobilenav.after(mobilenavDiv); -mobilenav_trigger.addEventListener('click', function (event) { - mobilenav.classList.toggle('toggled'); - if (mobilenav.classList.contains('toggled')) { - mobilenav.style.left = '0px'; - mobilenav.style.transition = '0.35s'; - mobilenavDiv.style.left = '0px'; - mobilenavDiv.style.transition = '0.35s'; - } else { - mobilenav.style.left = '-100%'; - mobilenav.style.transition = '0.35s'; - mobilenavDiv.style.left = '-100%'; - mobilenavDiv.style.transition = '0.35s'; - } -}); +var memberliteMobilenav_trigger = document.querySelector( 'button.menu-toggle' ), + memberliteMobilenav = document.getElementById( 'mobile-navigation' ), + memberliteMobilenavDiv = document.createElement( 'div' ); + +memberliteMobilenavDiv.setAttribute( 'id', 'mobile-navigation-height-col' ); +memberliteMobilenav.after( memberliteMobilenavDiv ); + +memberliteMobilenav_trigger.addEventListener( 'click', function ( event ) { + memberliteMobilenav.classList.toggle( 'toggled' ); + + if ( memberliteMobilenav.classList.contains( 'toggled' ) ) { + memberliteMobilenav.style.left = '0px'; + memberliteMobilenav.style.transition = '0.35s'; + memberliteMobilenavDiv.style.left = '0px'; + memberliteMobilenavDiv.style.transition = '0.35s'; + } + else { + memberliteMobilenav.style.left = '-100%'; + memberliteMobilenav.style.transition = '0.35s'; + memberliteMobilenavDiv.style.left = '-100%'; + memberliteMobilenavDiv.style.transition = '0.35s'; + } +} ); // skip link focus fix // borrowed from _s theme: https://git.io/vWdr2 -var isIe = /(trident|msie)/i.test(navigator.userAgent); +var memberliteIsIe = /(trident|msie)/i.test( navigator.userAgent ); -if (isIe && document.getElementById && window.addEventListener) { - window.addEventListener('hashchange', function () { - var id = location.hash.substring(1), - element; +if ( memberliteIsIe && document.getElementById && window.addEventListener ) { + window.addEventListener( 'hashchange', function () { + var id = location.hash.substring( 1 ), element; - if (!/^[A-z0-9_-]+$/.test(id)) { - return; - } + if ( ! /^[A-z0-9_-]+$/.test( id ) ) { + return; + } - element = document.getElementById(id); + element = document.getElementById( id ); - if (element) { - if (!/^(?:a|select|input|button|textarea)$/i.test(element.tagName)) { - element.tabIndex = -1; - } + if ( element ) { + if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) { + element.tabIndex = -1; + } - element.focus(); - } - }, false); -} \ No newline at end of file + element.focus(); + } + }, false ); +} From 420c4bf076c39d4666a1d69f9d3b9ca3d10746b0 Mon Sep 17 00:00:00 2001 From: Scott Kingsley Clark Date: Wed, 27 Oct 2021 17:19:02 -0500 Subject: [PATCH 10/10] Refresh minified JS --- js/memberlite.min.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/memberlite.min.js b/js/memberlite.min.js index 36d2a82..1596048 100644 --- a/js/memberlite.min.js +++ b/js/memberlite.min.js @@ -1 +1,2 @@ -(function(){function p(){}function q(b){return null==b?b===a?m:c:G&&G in Object(b)?e(b):n(b)}function e(b){var c=C.call(b,G),d=b[G];try{b[G]=a;var e=!0}catch(a){}var f=E.call(b);return e&&(c?b[G]=d:delete b[G]),f}function n(a){return E.call(a)}function z(b,q,t){function n(c){var d=m,e=z;return m=z=a,F=c,C=b.apply(e,d)}function r(a){return F=a,D=setTimeout(f,q),G?n(a):C}function o(a){var b=a-E,c=a-F,d=q-b;return J?I(d,B-c):d}function i(b){var c=b-E,d=b-F;return E===a||c>=q||0>c||J&&d>=B}function f(){var b=k();return i(b)?c(b):(D=setTimeout(f,o(b)),a)}function c(b){return D=a,K&&m?n(b):(m=z=a,C)}function p(){D!==a&&clearTimeout(D),F=0,m=E=z=D=a}function s(){return D===a?C:c(k())}function y(){var b=k(),c=i(b);if(m=arguments,z=this,E=b,c){if(D===a)return r(E);if(J)return D=setTimeout(f,q),n(E)}return D===a&&(D=setTimeout(f,q)),C}var m,z,B,C,D,E,F=0,G=!1,J=!1,K=!0;if("function"!=typeof b)throw new TypeError(l);return q=u(q)||0,A(t)&&(G=!!t.leading,J="maxWait"in t,B=J?H(u(t.maxWait)||0,q):B,K="trailing"in t?!!t.trailing:K),y.cancel=p,y.flush=s,y}function o(a,b,c){var d=!0,e=!0;if("function"!=typeof a)throw new TypeError(l);return A(c)&&(d="leading"in c?!!c.leading:d,e="trailing"in c?!!c.trailing:e),z(a,b,{leading:d,maxWait:b,trailing:e})}function A(a){var b=typeof a;return null!=a&&("object"==b||"function"==b)}function i(a){return null!=a&&"object"==typeof a}function f(a){return"symbol"==typeof a||i(a)&&q(a)==r}function u(a){if("number"==typeof a)return a;if(f(a))return b;if(A(a)){var c="function"==typeof a.valueOf?a.valueOf():a;a=A(c)?c+"":c}if("string"!=typeof a)return 0===a?a:+a;a=a.replace(d,"");var e=j.test(a);return e||s.test(a)?v(a.slice(2),e?2:8):g.test(a)?b:+a}var a,l="Expected a function",b=NaN,c="[object Null]",r="[object Symbol]",m="[object Undefined]",d=/^\s+|\s+$/g,g=/^[-+]0x[0-9a-f]+$/i,j=/^0b[01]+$/i,s=/^0o[0-7]+$/i,v=parseInt,h="object"==typeof global&&global&&global.Object===Object&&global,t="object"==typeof self&&self&&self.Object===Object&&self,x=h||t||Function("return this")(),w="object"==typeof exports&&exports&&!exports.nodeType&&exports,y=w&&"object"==typeof module&&module&&!module.nodeType&&module,B=Object.prototype,C=B.hasOwnProperty,E=B.toString,F=x.Symbol,G=F?F.toStringTag:a,H=Math.max,I=Math.min,k=function(){return x.Date.now()};p.debounce=z,p.throttle=o,p.isObject=A,p.isObjectLike=i,p.isSymbol=f,p.now=k,p.toNumber=u,p.VERSION="4.17.5","function"==typeof define&&"object"==typeof define.amd&&define.amd?(x._=p,define(function(){return p})):y?((y.exports=p)._=p,w._=p):x._=p}).call(this);const anchorLinks=document.querySelectorAll("[href*=\"#\"]:not([data-toggle=\"tab\"])"),memberliteSiteNavigation=document.getElementById("site-navigation"),memberliteSiteNavigationSticky=document.querySelector(".site-navigation-sticky-wrapper");function getElementHeight(a){return null==a?0:a.clientHeight}function offsetH(a){var b=a.getBoundingClientRect(),c=window.pageYOffset||document.documentElement.scrollTop;return parseInt(b.top+c)}var simulateClick=function(a){var b=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window}),c=!a.dispatchEvent(b)};function memberliteSmootScroll(a,b=0){a.forEach(a=>{a.addEventListener("click",a=>{a.preventDefault();let c=document.querySelector(a.target.hash);c.scrollIntoView({behavior:"smooth",block:"start"}),b=b+getElementHeight(document.getElementById("wpadminbar"))+(null==memberliteSiteNavigationSticky?0:getElementHeight(memberliteSiteNavigation)),b&&setTimeout(()=>{window.scrollBy({top:-b,behavior:"smooth"}),b=0},500{let a=Math.round(window.scrollY);a>getElementHeight(memberliteSiteNavigation)?memberliteSiteNavigation.classList.add("site-navigation-sticky"):memberliteSiteNavigation.classList.remove("site-navigation-sticky")},300);null!=memberliteSiteNavigationSticky&&window.addEventListener("scroll",memberliteStickyNav);const memberliteTabAnchors=document.querySelectorAll(".memberlite_tabbable .memberlite_tabs li a");null!=memberliteTabAnchors&&memberliteTabAnchors.forEach(a=>{a.getAttribute("href");a.addEventListener("click",function(a){a.preventDefault();const b=this.getAttribute("href").replace(/#/,""),c=this.closest(".memberlite_tabbable"),d=c.querySelectorAll(".memberlite_tab_pane");for(let b=0;b=t||i<0||w&&e-p>=d}function s(){var e=I();return c(e)?b(e):(y=setTimeout(s,function(e){var i=t-(e-h);return w?_(i,d-(e-p)):i}(e)),a)}function b(e){return y=a,E&&f?r(e):(f=v=a,g)}function u(){var e=I(),i=c(e);if(f=arguments,v=this,h=e,i){if(y===a)return l(h);if(w)return y=setTimeout(s,t),r(h)}return y===a&&(y=setTimeout(s,t)),g}var f,v,d,g,y,h,p=0,S=!1,w=!1,E=!0;if("function"!=typeof e)throw new TypeError(m);return t=o(t)||0,n(i)&&(S=!!i.leading,d=(w="maxWait"in i)?L(o(i.maxWait)||0,t):d,E="trailing"in i?!!i.trailing:E),u.cancel=function(){y!==a&&clearTimeout(y),p=0,f=h=v=y=a},u.flush=function(){return y===a?g:b(I())},u}function n(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}function r(e){return null!=e&&"object"==typeof e}function l(e){return"symbol"==typeof e||r(e)&&t(e)==b}function o(e){if("number"==typeof e)return e;if(l(e))return c;if(n(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=n(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(f,"");var i=d.test(e);return i||g.test(e)?y(e.slice(2),i?2:8):v.test(e)?c:+e}var a,m="Expected a function",c=NaN,s="[object Null]",b="[object Symbol]",u="[object Undefined]",f=/^\s+|\s+$/g,v=/^[-+]0x[0-9a-f]+$/i,d=/^0b[01]+$/i,g=/^0o[0-7]+$/i,y=parseInt,h="object"==typeof global&&global&&global.Object===Object&&global,p="object"==typeof self&&self&&self.Object===Object&&self,S=h||p||Function("return this")(),w="object"==typeof exports&&exports&&!exports.nodeType&&exports,E=w&&"object"==typeof module&&module&&!module.nodeType&&module,M=Object.prototype,T=M.hasOwnProperty,k=M.toString,j=S.Symbol,A=j?j.toStringTag:a,L=Math.max,_=Math.min,I=function(){return S.Date.now()};e.debounce=i,e.throttle=function(e,t,r){var l=!0,o=!0;if("function"!=typeof e)throw new TypeError(m);return n(r)&&(l="leading"in r?!!r.leading:l,o="trailing"in r?!!r.trailing:o),i(e,t,{leading:l,maxWait:t,trailing:o})},e.isObject=n,e.isObjectLike=r,e.isSymbol=l,e.now=I,e.toNumber=o,e.VERSION="4.17.5","function"==typeof define&&"object"==typeof define.amd&&define.amd?(S._=e,define((function(){return e}))):E?((E.exports=e)._=e,w._=e):S._=e}).call(this);var memberliteLinks=document.querySelectorAll('[href*="#"]:not([data-toggle="tab"])'),memberliteSiteNavigation=document.getElementById("site-navigation"),memberliteSiteNavigationSticky=document.querySelector(".site-navigation-sticky-wrapper");function memberliteGetElementHeight(e){return null!=e?e.clientHeight:0}function memberliteOffsetH(e){var t=e.getBoundingClientRect(),i=window.pageYOffset||document.documentElement.scrollTop;return parseInt(t.top+i)}var memberliteSimulateClick=function(e){var t=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window});e.dispatchEvent(t)};function memberliteSmootScroll(e){var t=arguments.length<=1||void 0===arguments[1]?0:arguments[1],i=Array.prototype.slice.call(e);i.forEach((function(e){e.addEventListener("click",(function(e){e.preventDefault();var i=document.querySelector(e.target.hash);i.scrollIntoView({behavior:"smooth",block:"start"}),(t=t+memberliteGetElementHeight(document.getElementById("wpadminbar"))+(null!=memberliteSiteNavigationSticky?memberliteGetElementHeight(memberliteSiteNavigation):0))&&setTimeout((function(){window.scrollBy({top:-t,behavior:"smooth"}),t=0}),memberliteOffsetH(i)/6>500?parseInt(memberliteOffsetH(i)/6):500)}))}))}memberliteSmootScroll(memberliteLinks);var memberliteStickyNav=_.throttle((function(){Math.round(window.scrollY)>memberliteGetElementHeight(memberliteSiteNavigation)?memberliteSiteNavigation.classList.add("site-navigation-sticky"):memberliteSiteNavigation.classList.remove("site-navigation-sticky")}),300);null!=memberliteSiteNavigationSticky&&window.addEventListener("scroll",memberliteStickyNav);var memberliteTabAnchors=document.querySelectorAll(".memberlite_tabbable .memberlite_tabs li a");if(null!=memberliteTabAnchors){var memberliteTabAnchorsArray=Array.prototype.slice.call(memberliteTabAnchors);memberliteTabAnchorsArray.forEach((function(e){e.getAttribute("href");e.addEventListener("click",(function(e,t){e.preventDefault();for(var i=this.getAttribute("href").replace(/#/,""),n=this.closest(".memberlite_tabbable"),r=n.querySelectorAll(".memberlite_tab_pane"),l=0;l