frontend.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  1. /**
  2. * File fronend.js
  3. *
  4. * Handles toggling the navigation menu for small screens and enables tab
  5. * support for dropdown menus.
  6. *
  7. * @package Astra
  8. */
  9. /**
  10. * Get all of an element's parent elements up the DOM tree
  11. *
  12. * @param {Node} elem The element.
  13. * @param {String} selector Selector to match against [optional].
  14. * @return {Array} The parent elements.
  15. */
  16. var astraGetParents = function ( elem, selector ) {
  17. // Element.matches() polyfill.
  18. if ( ! Element.prototype.matches) {
  19. Element.prototype.matches =
  20. Element.prototype.matchesSelector ||
  21. Element.prototype.mozMatchesSelector ||
  22. Element.prototype.msMatchesSelector ||
  23. Element.prototype.oMatchesSelector ||
  24. Element.prototype.webkitMatchesSelector ||
  25. function(s) {
  26. var matches = (this.document || this.ownerDocument).querySelectorAll( s ),
  27. i = matches.length;
  28. while (--i >= 0 && matches.item( i ) !== this) {}
  29. return i > -1;
  30. };
  31. }
  32. // Setup parents array.
  33. var parents = [];
  34. // Get matching parent elements.
  35. for ( ; elem && elem !== document; elem = elem.parentNode ) {
  36. // Add matching parents to array.
  37. if ( selector ) {
  38. if ( elem.matches( selector ) ) {
  39. parents.push( elem );
  40. }
  41. } else {
  42. parents.push( elem );
  43. }
  44. }
  45. return parents;
  46. };
  47. /**
  48. * Deprecated: Get all of an element's parent elements up the DOM tree
  49. *
  50. * @param {Node} elem The element.
  51. * @param {String} selector Selector to match against [optional].
  52. * @return {Array} The parent elements.
  53. */
  54. var getParents = function ( elem, selector ) {
  55. console.warn( 'getParents() function has been deprecated since version 2.5.0 or above of Astra Theme and will be removed in the future. Use astraGetParents() instead.' );
  56. astraGetParents( elem, selector );
  57. }
  58. /**
  59. * Toggle Class funtion
  60. *
  61. * @param {Node} elem The element.
  62. * @param {String} selector Selector to match against [optional].
  63. * @return {Array} The parent elements.
  64. */
  65. var astraToggleClass = function ( el, className ) {
  66. if ( el.classList.contains( className ) ) {
  67. el.classList.remove( className );
  68. } else {
  69. el.classList.add( className );
  70. }
  71. };
  72. /**
  73. * Deprecated: Toggle Class funtion
  74. *
  75. * @param {Node} elem The element.
  76. * @param {String} selector Selector to match against [optional].
  77. * @return {Array} The parent elements.
  78. */
  79. var toggleClass = function ( el, className ) {
  80. console.warn( 'toggleClass() function has been deprecated since version 2.5.0 or above of Astra Theme and will be removed in the future. Use astraToggleClass() instead.' );
  81. astraToggleClass( el, className );
  82. };
  83. // CustomEvent() constructor functionality in Internet Explorer 9 and higher.
  84. (function () {
  85. if (typeof window.CustomEvent === "function") return false;
  86. function CustomEvent(event, params) {
  87. params = params || { bubbles: false, cancelable: false, detail: undefined };
  88. var evt = document.createEvent('CustomEvent');
  89. evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
  90. return evt;
  91. }
  92. CustomEvent.prototype = window.Event.prototype;
  93. window.CustomEvent = CustomEvent;
  94. })();
  95. /**
  96. * Trigget custom JS Event.
  97. *
  98. * @since 1.4.6
  99. *
  100. * @link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent
  101. * @param {Node} el Dom Node element on which the event is to be triggered.
  102. * @param {Node} typeArg A DOMString representing the name of the event.
  103. * @param {String} A CustomEventInit dictionary, having the following fields:
  104. * "detail", optional and defaulting to null, of type any, that is an event-dependent value associated with the event.
  105. */
  106. var astraTriggerEvent = function astraTriggerEvent( el, typeArg ) {
  107. var customEventInit =
  108. arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  109. var event = new CustomEvent(typeArg, customEventInit);
  110. el.dispatchEvent(event);
  111. };
  112. ( function() {
  113. var menu_toggle_all = document.querySelectorAll( '#masthead .main-header-menu-toggle' ),
  114. main_header_masthead = document.getElementById('masthead'),
  115. menu_click_listeners = {},
  116. mobileHeaderType = '',
  117. body = document.body,
  118. mobileHeader = '';
  119. if ( undefined !== main_header_masthead && null !== main_header_masthead ) {
  120. mobileHeader = main_header_masthead.querySelector("#ast-mobile-header");
  121. }
  122. if ( '' !== mobileHeader && null !== mobileHeader ) {
  123. mobileHeaderType = mobileHeader.dataset.type;
  124. }
  125. document.addEventListener( 'astMobileHeaderTypeChange', updateHeaderType, false );
  126. /**
  127. * Updates the header type.
  128. */
  129. function updateHeaderType( e ) {
  130. mobileHeaderType = e.detail.type;
  131. var popupTrigger = document.querySelectorAll( '.menu-toggle' );
  132. if( 'dropdown' === mobileHeaderType ) {
  133. document.getElementById( 'ast-mobile-popup' ).classList.remove( 'active', 'show' );
  134. updateTrigger('updateHeader');
  135. }
  136. if ( 'off-canvas' === mobileHeaderType ) {
  137. for ( var item = 0; item < popupTrigger.length; item++ ) {
  138. if ( undefined !== popupTrigger[item] && popupTrigger[item].classList.contains( 'toggled') ) {
  139. popupTrigger[item].click();
  140. }
  141. }
  142. }
  143. init( mobileHeaderType );
  144. }
  145. /**
  146. * Opens the Popup when trigger is clicked.
  147. */
  148. popupTriggerClick = function ( event ) {
  149. var triggerType = event.currentTarget.trigger_type;
  150. var popupWrap = document.getElementById( 'ast-mobile-popup' );
  151. if ( ! body.classList.contains( 'ast-popup-nav-open' ) ) {
  152. body.classList.add( 'ast-popup-nav-open' );
  153. }
  154. if ( ! body.classList.contains( 'ast-main-header-nav-open' ) && 'mobile' !== triggerType ) {
  155. body.classList.add( 'ast-main-header-nav-open' );
  156. }
  157. if ( ! document.documentElement.classList.contains( 'ast-off-canvas-active' ) ) {
  158. document.documentElement.classList.add( 'ast-off-canvas-active' );
  159. }
  160. if ( 'desktop' === triggerType ) {
  161. popupWrap.querySelector( '.ast-mobile-popup-content' ).style.display = 'none';
  162. popupWrap.querySelector( '.ast-desktop-popup-content' ).style.display = 'block';
  163. }
  164. if ( 'mobile' === triggerType ) {
  165. popupWrap.querySelector( '.ast-desktop-popup-content' ).style.display = 'none';
  166. popupWrap.querySelector( '.ast-mobile-popup-content' ).style.display = 'block';
  167. }
  168. this.style.display = 'none';
  169. popupWrap.classList.add( 'active', 'show' );
  170. }
  171. /**
  172. * Closes the Trigger when Popup is Closed.
  173. */
  174. function updateTrigger(currentElement) {
  175. mobileHeader = main_header_masthead.querySelector( "#ast-mobile-header" );
  176. var parent_li_sibling = '';
  177. if( undefined !== mobileHeader && null !== mobileHeader && 'dropdown' === mobileHeader.dataset.type && 'updateHeader' !== currentElement ) {
  178. return;
  179. }
  180. if ( undefined !== currentElement && 'updateHeader' !== currentElement ) {
  181. parent_li_sibling = currentElement.closest( '.ast-mobile-popup-inner' ).querySelectorAll('.menu-item-has-children');
  182. } else {
  183. var popup = document.querySelector( '#ast-mobile-popup' );
  184. parent_li_sibling = popup.querySelectorAll('.menu-item-has-children');
  185. }
  186. for ( var j = 0; j < parent_li_sibling.length; j++ ) {
  187. parent_li_sibling[j].classList.remove('ast-submenu-expanded');
  188. var all_sub_menu = parent_li_sibling[j].querySelectorAll('.sub-menu');
  189. for ( var k = 0; k < all_sub_menu.length; k++ ) {
  190. all_sub_menu[k].style.display = 'none';
  191. }
  192. }
  193. var popupTrigger = document.querySelectorAll( '.menu-toggle' );
  194. document.body.classList.remove( 'ast-main-header-nav-open', 'ast-popup-nav-open' );
  195. document.documentElement.classList.remove( 'ast-off-canvas-active' );
  196. for ( var item = 0; item < popupTrigger.length; item++ ) {
  197. popupTrigger[item].classList.remove( 'toggled' );
  198. popupTrigger[item].style.display = 'flex';
  199. }
  200. }
  201. /**
  202. * Main Init Function.
  203. */
  204. function init( mobileHeaderType ) {
  205. var popupTriggerMobile = document.querySelectorAll( '#ast-mobile-header .menu-toggle' );
  206. var popupTriggerDesktop = document.querySelectorAll( '#ast-desktop-header .menu-toggle' );
  207. if ( undefined === mobileHeaderType && null !== main_header_masthead ) {
  208. mobileHeader = main_header_masthead.querySelector("#ast-mobile-header");
  209. if( mobileHeader ) {
  210. mobileHeaderType = mobileHeader.dataset.type;
  211. } else {
  212. var desktopHeader = main_header_masthead.querySelector("#ast-desktop-header");
  213. if ( desktopHeader ) {
  214. mobileHeaderType = desktopHeader.dataset.toggleType;
  215. } else {
  216. return;
  217. }
  218. }
  219. }
  220. if ( 'off-canvas' === mobileHeaderType ) {
  221. var popupClose = document.getElementById( 'menu-toggle-close' ),
  222. popupInner = document.querySelector( '.ast-mobile-popup-inner' );
  223. if ( undefined === popupInner || null === popupInner ){
  224. return; // if toggel button component is not loaded.
  225. }
  226. popupLinks = popupInner.getElementsByTagName('a');
  227. for ( var item = 0; item < popupTriggerMobile.length; item++ ) {
  228. popupTriggerMobile[item].removeEventListener("click", astraNavMenuToggle, false);
  229. // Open the Popup when click on trigger
  230. popupTriggerMobile[item].addEventListener("click", popupTriggerClick, false);
  231. popupTriggerMobile[item].trigger_type = 'mobile';
  232. }
  233. for ( var item = 0; item < popupTriggerDesktop.length; item++ ) {
  234. popupTriggerDesktop[item].removeEventListener("click", astraNavMenuToggle, false);
  235. // Open the Popup when click on trigger
  236. popupTriggerDesktop[item].addEventListener("click", popupTriggerClick, false);
  237. popupTriggerDesktop[item].trigger_type = 'desktop';
  238. }
  239. //Close Popup on CLose Button Click.
  240. popupClose.addEventListener("click", function( e ) {
  241. document.getElementById( 'ast-mobile-popup' ).classList.remove( 'active', 'show' );
  242. updateTrigger(this);
  243. });
  244. // Close Popup if esc is pressed.
  245. document.addEventListener( 'keyup', function (event) {
  246. // 27 is keymap for esc key.
  247. if ( event.keyCode === 27 ) {
  248. event.preventDefault();
  249. document.getElementById( 'ast-mobile-popup' ).classList.remove( 'active', 'show' );
  250. updateTrigger();
  251. }
  252. });
  253. // Close Popup on outside click.
  254. document.addEventListener('click', function (event) {
  255. var target = event.target;
  256. var modal = document.querySelector( '.ast-mobile-popup-drawer.active .ast-mobile-popup-overlay' );
  257. if ( target === modal ) {
  258. document.getElementById( 'ast-mobile-popup' ).classList.remove( 'active', 'show' );
  259. updateTrigger();
  260. }
  261. });
  262. // Close Popup on # link click inside Popup.
  263. for ( let link = 0, len = popupLinks.length; link < len; link++ ) {
  264. if( null !== popupLinks[link].getAttribute("href") && ( popupLinks[link].getAttribute("href").startsWith('#') || -1 !== popupLinks[link].getAttribute("href").search("#") ) && ( ! popupLinks[link].parentElement.classList.contains('menu-item-has-children') || ( popupLinks[link].parentElement.classList.contains('menu-item-has-children') && document.querySelector('header.site-header').classList.contains('ast-builder-menu-toggle-icon') ) ) ){
  265. popupLinks[link].addEventListener( 'click', triggerToggleClose, true );
  266. popupLinks[link].headerType = 'off-canvas';
  267. }
  268. }
  269. AstraToggleSetup();
  270. } else if ( 'dropdown' === mobileHeaderType ) {
  271. var mobileDropdownContent = document.querySelectorAll( '.ast-mobile-header-content' ) || false,
  272. desktopDropdownContent = document.querySelector( '.ast-desktop-header-content' ) || false;
  273. // Close Popup on # link click inside Popup.
  274. if ( mobileDropdownContent.length > 0 ) {
  275. for ( let index = 0; index < mobileDropdownContent.length; index++ ) {
  276. var mobileLinks = mobileDropdownContent[index].getElementsByTagName('a');
  277. for ( link = 0, len = mobileLinks.length; link < len; link++ ) {
  278. if ( null !== mobileLinks[link].getAttribute("href") && ( mobileLinks[link].getAttribute("href").startsWith('#') || -1 !== mobileLinks[link].getAttribute("href").search("#") ) && ( !mobileLinks[link].parentElement.classList.contains('menu-item-has-children') || ( mobileLinks[link].parentElement.classList.contains('menu-item-has-children') && document.querySelector('header.site-header').classList.contains('ast-builder-menu-toggle-icon') ) ) ) {
  279. mobileLinks[link].addEventListener( 'click', triggerToggleClose, true );
  280. mobileLinks[link].headerType = 'dropdown';
  281. }
  282. }
  283. }
  284. }
  285. // Close Popup on # link click inside Popup.
  286. if( desktopDropdownContent ) {
  287. var desktopLinks = desktopDropdownContent.getElementsByTagName('a');
  288. for ( link = 0, len = desktopLinks.length; link < len; link++ ) {
  289. desktopLinks[link].addEventListener( 'click', triggerToggleClose, true );
  290. desktopLinks[link].headerType = 'dropdown';
  291. }
  292. }
  293. for ( var item = 0; item < popupTriggerMobile.length; item++ ) {
  294. popupTriggerMobile[item].removeEventListener("click", popupTriggerClick, false);
  295. popupTriggerMobile[item].addEventListener('click', astraNavMenuToggle, false);
  296. popupTriggerMobile[item].trigger_type = 'mobile';
  297. }
  298. for ( var item = 0; item < popupTriggerDesktop.length; item++ ) {
  299. popupTriggerDesktop[item].removeEventListener("click", popupTriggerClick, false);
  300. popupTriggerDesktop[item].addEventListener('click', astraNavMenuToggle, false);
  301. popupTriggerDesktop[item].trigger_type = 'desktop';
  302. }
  303. AstraToggleSetup();
  304. }
  305. accountPopupTrigger();
  306. }
  307. function triggerToggleClose( event ) {
  308. var headerType = event.currentTarget.headerType;
  309. switch( headerType ) {
  310. case 'dropdown':
  311. var popupTrigger = document.querySelectorAll( '.menu-toggle.toggled' );
  312. for ( var item = 0; item < popupTrigger.length; item++ ) {
  313. popupTrigger[item].click();
  314. }
  315. break;
  316. case 'off-canvas':
  317. var popupClose = document.getElementById( 'menu-toggle-close' );
  318. popupClose.click();
  319. break;
  320. default:
  321. break;
  322. }
  323. }
  324. window.addEventListener( 'load', function() {
  325. init();
  326. } );
  327. document.addEventListener( 'astLayoutWidthChanged', function() {
  328. init();
  329. } );
  330. document.addEventListener( 'astPartialContentRendered', function() {
  331. menu_toggle_all = document.querySelectorAll( '.main-header-menu-toggle' );
  332. body.classList.remove("ast-main-header-nav-open");
  333. document.addEventListener( 'astMobileHeaderTypeChange', updateHeaderType, false );
  334. init();
  335. accountPopupTrigger();
  336. } );
  337. var mobile_width = ( 'Android' === navigator.userAgent.match(/Android/i) ) ? window.visualViewport.width : window.innerWidth;
  338. function AstraHandleResizeEvent() {
  339. var menu_offcanvas_close = document.getElementById('menu-toggle-close');
  340. var menu_dropdown_close = document.querySelector('.menu-toggle.toggled');
  341. var desktop_header_content = document.querySelector('#masthead > #ast-desktop-header .ast-desktop-header-content');
  342. var elementor_editor = document.querySelector('.elementor-editor-active');
  343. if ( desktop_header_content ) {
  344. desktop_header_content.style.display = 'none';
  345. }
  346. var mobileResizeWidth = ( 'Android' === navigator.userAgent.match(/Android/i) ) ? window.visualViewport.width : window.innerWidth;
  347. if ( mobileResizeWidth !== mobile_width ) {
  348. if ( menu_dropdown_close && null === elementor_editor ) {
  349. menu_dropdown_close.click();
  350. }
  351. document.body.classList.remove( 'ast-main-header-nav-open', 'ast-popup-nav-open' );
  352. if( menu_offcanvas_close && null == elementor_editor ) {
  353. menu_offcanvas_close.click();
  354. }
  355. }
  356. updateHeaderBreakPoint();
  357. AstraToggleSetup();
  358. }
  359. window.addEventListener('resize', function(){
  360. // Skip resize event when keyboard display event triggers on devices.
  361. if( 'INPUT' !== document.activeElement.tagName ) {
  362. AstraHandleResizeEvent();
  363. }
  364. } );
  365. document.addEventListener('DOMContentLoaded', function () {
  366. AstraToggleSetup();
  367. /**
  368. * Navigation Keyboard Navigation.
  369. */
  370. var containerButton;
  371. if ( body.classList.contains('ast-header-break-point') ) {
  372. containerButton = document.getElementById( 'ast-mobile-header' );
  373. } else {
  374. containerButton = document.getElementById( 'ast-desktop-header' );
  375. }
  376. if( null !== containerButton ) {
  377. var containerMenu = containerButton.querySelector( '.navigation-accessibility' );
  378. navigation_accessibility( containerMenu, containerButton );
  379. }
  380. });
  381. var get_window_width = function () {
  382. return document.documentElement.clientWidth;
  383. }
  384. /* Add break point Class and related trigger */
  385. var updateHeaderBreakPoint = function () {
  386. // Content overrflowing out of screen can give incorrect window.innerWidth.
  387. // Adding overflow hidden and then calculating the window.innerWidth fixes the problem.
  388. var originalOverflow = body.style.overflow;
  389. body.style.overflow = 'hidden';
  390. var ww = get_window_width();
  391. body.style.overflow = originalOverflow;
  392. var break_point = astra.break_point;
  393. /**
  394. * This case is when one hits a URL one after the other via `Open in New Tab` option
  395. * Chrome returns the value of outer width as 0 in this case.
  396. * This mis-calculates the width of the window and header seems invisible.
  397. * This could be fixed by using `0 === ww` condition below.
  398. */
  399. if (ww > break_point || 0 === ww) {
  400. //remove menu toggled class.
  401. if ( menu_toggle_all.length > 0 ) {
  402. for (var i = 0; i < menu_toggle_all.length; i++) {
  403. if( null !== menu_toggle_all[i] ) {
  404. menu_toggle_all[i].classList.remove('toggled');
  405. }
  406. }
  407. }
  408. body.classList.remove("ast-header-break-point");
  409. body.classList.add("ast-desktop");
  410. astraTriggerEvent(body, "astra-header-responsive-enabled");
  411. } else {
  412. body.classList.add("ast-header-break-point");
  413. body.classList.remove("ast-desktop");
  414. astraTriggerEvent(body, "astra-header-responsive-disabled")
  415. }
  416. }
  417. var accountPopupTrigger = function () {
  418. // Account login form popup.
  419. var header_account_trigger = document.querySelectorAll( '.ast-account-action-login' );
  420. if ( undefined !== header_account_trigger ) {
  421. var header_account__close_trigger = document.querySelectorAll( '#ast-hb-login-close' );
  422. var login_popup = document.querySelectorAll('#ast-hb-account-login-wrap');
  423. if ( 0 < header_account__close_trigger.length ) {
  424. for ( let index = 0; index < header_account_trigger.length; index++ ) {
  425. header_account_trigger[ index ].onclick = function (event) {
  426. event.preventDefault();
  427. event.stopPropagation();
  428. if ( ! login_popup[ index ].classList.contains('show')) {
  429. login_popup[ index ].classList.add('show');
  430. }
  431. };
  432. header_account__close_trigger[ index ].onclick = function (event) {
  433. event.preventDefault();
  434. login_popup[ index ].classList.remove('show');
  435. };
  436. }
  437. }
  438. }
  439. }
  440. updateHeaderBreakPoint();
  441. AstraToggleSubMenu = function( event ) {
  442. event.preventDefault();
  443. var parent_li = this.parentNode;
  444. if ( parent_li.classList.contains('ast-submenu-expanded') && document.querySelector('header.site-header').classList.contains('ast-builder-menu-toggle-link') ) {
  445. if (!this.classList.contains('ast-menu-toggle')) {
  446. var link = parent_li.querySelector('a').getAttribute('href');
  447. if ( '' !== link && '#' !== link) {
  448. window.location = link;
  449. }
  450. }
  451. }
  452. var parent_li_child = parent_li.querySelectorAll('.menu-item-has-children');
  453. for (var j = 0; j < parent_li_child.length; j++) {
  454. parent_li_child[j].classList.remove('ast-submenu-expanded');
  455. var parent_li_child_sub_menu = parent_li_child[j].querySelector('.sub-menu, .children');
  456. if( null !== parent_li_child_sub_menu ) {
  457. parent_li_child_sub_menu.style.display = 'none';
  458. }
  459. }
  460. var parent_li_sibling = parent_li.parentNode.querySelectorAll('.menu-item-has-children');
  461. for (var j = 0; j < parent_li_sibling.length; j++) {
  462. if (parent_li_sibling[j] != parent_li) {
  463. parent_li_sibling[j].classList.remove('ast-submenu-expanded');
  464. var all_sub_menu = parent_li_sibling[j].querySelectorAll('.sub-menu');
  465. for (var k = 0; k < all_sub_menu.length; k++) {
  466. all_sub_menu[k].style.display = 'none';
  467. }
  468. }
  469. }
  470. if (parent_li.classList.contains('menu-item-has-children') ) {
  471. astraToggleClass(parent_li, 'ast-submenu-expanded');
  472. if (parent_li.classList.contains('ast-submenu-expanded')) {
  473. parent_li.querySelector('.sub-menu').style.display = 'block';
  474. } else {
  475. parent_li.querySelector('.sub-menu').style.display = 'none';
  476. }
  477. }
  478. };
  479. AstraToggleSetup = function () {
  480. if( typeof astraAddon != 'undefined' ) {
  481. astraToggleSetupPro( mobileHeaderType, body, menu_click_listeners );
  482. } else {
  483. var flag = false;
  484. var menuToggleAllLength;
  485. if ( 'off-canvas' === mobileHeaderType || 'full-width' === mobileHeaderType ) {
  486. // comma separated selector added, if menu is outside of Off-Canvas then submenu is not clickable, it work only for Off-Canvas area with dropdown style.
  487. var __main_header_all = document.querySelectorAll( '#ast-mobile-popup, #ast-mobile-header' );
  488. var menu_toggle_all = document.querySelectorAll('#ast-mobile-header .main-header-menu-toggle');
  489. menuToggleAllLength = menu_toggle_all.length;
  490. } else {
  491. var __main_header_all = document.querySelectorAll( '#ast-mobile-header' ),
  492. menu_toggle_all = document.querySelectorAll('#ast-mobile-header .main-header-menu-toggle');
  493. menuToggleAllLength = menu_toggle_all.length;
  494. flag = menuToggleAllLength > 0 ? false : true;
  495. menuToggleAllLength = flag ? 1 : menuToggleAllLength;
  496. }
  497. if ( menuToggleAllLength > 0 || flag ) {
  498. for (var i = 0; i < menuToggleAllLength; i++) {
  499. if ( ! flag ) {
  500. menu_toggle_all[i].setAttribute('data-index', i);
  501. if ( ! menu_click_listeners[i] ) {
  502. menu_click_listeners[i] = menu_toggle_all[i];
  503. menu_toggle_all[i].addEventListener('click', astraNavMenuToggle, false);
  504. }
  505. }
  506. if ('undefined' !== typeof __main_header_all[i]) {
  507. // To handle the comma seprated selector added above we need this loop.
  508. for( var mainHeaderCount =0; mainHeaderCount < __main_header_all.length; mainHeaderCount++ ){
  509. if (document.querySelector('header.site-header').classList.contains('ast-builder-menu-toggle-link')) {
  510. var astra_menu_toggle = __main_header_all[mainHeaderCount].querySelectorAll('ul.main-header-menu .menu-item-has-children > .menu-link, ul.main-header-menu .ast-menu-toggle');
  511. } else {
  512. var astra_menu_toggle = __main_header_all[mainHeaderCount].querySelectorAll('ul.main-header-menu .ast-menu-toggle');
  513. }
  514. // Add Eventlisteners for Submenu.
  515. if (astra_menu_toggle.length > 0) {
  516. for (var j = 0; j < astra_menu_toggle.length; j++) {
  517. astra_menu_toggle[j].addEventListener('click', AstraToggleSubMenu, false);
  518. }
  519. }
  520. }
  521. }
  522. }
  523. }
  524. }
  525. };
  526. astraNavMenuToggle = function ( event ) {
  527. if( typeof astraAddon != 'undefined' ) {
  528. astraNavMenuTogglePro( event, body, mobileHeaderType, this );
  529. } else {
  530. event.preventDefault();
  531. var __main_header_all = document.querySelectorAll('#masthead > #ast-mobile-header .main-header-bar-navigation');
  532. menu_toggle_all = document.querySelectorAll( '#masthead > #ast-mobile-header .main-header-menu-toggle' )
  533. var event_index = '0';
  534. if ( null !== this.closest( '#ast-fixed-header' ) ) {
  535. __main_header_all = document.querySelectorAll('#ast-fixed-header > #ast-mobile-header .main-header-bar-navigation');
  536. menu_toggle_all = document.querySelectorAll( '#ast-fixed-header .main-header-menu-toggle' )
  537. event_index = '0';
  538. }
  539. if ('undefined' === typeof __main_header_all[event_index]) {
  540. return false;
  541. }
  542. var menuHasChildren = __main_header_all[event_index].querySelectorAll('.menu-item-has-children');
  543. for (var i = 0; i < menuHasChildren.length; i++) {
  544. menuHasChildren[i].classList.remove('ast-submenu-expanded');
  545. var menuHasChildrenSubMenu = menuHasChildren[i].querySelectorAll('.sub-menu');
  546. for (var j = 0; j < menuHasChildrenSubMenu.length; j++) {
  547. menuHasChildrenSubMenu[j].style.display = 'none';
  548. }
  549. }
  550. var menu_class = this.getAttribute('class') || '';
  551. if ( menu_class.indexOf('main-header-menu-toggle') !== -1 ) {
  552. astraToggleClass(__main_header_all[event_index], 'toggle-on');
  553. astraToggleClass(menu_toggle_all[event_index], 'toggled');
  554. if (__main_header_all[event_index].classList.contains('toggle-on')) {
  555. __main_header_all[event_index].style.display = 'block';
  556. body.classList.add("ast-main-header-nav-open");
  557. } else {
  558. __main_header_all[event_index].style.display = '';
  559. body.classList.remove("ast-main-header-nav-open");
  560. }
  561. }
  562. }
  563. };
  564. body.addEventListener("astra-header-responsive-enabled", function () {
  565. var __main_header_all = document.querySelectorAll('.main-header-bar-navigation');
  566. if (__main_header_all.length > 0) {
  567. for (var i = 0; i < __main_header_all.length; i++) {
  568. if (null != __main_header_all[i]) {
  569. __main_header_all[i].classList.remove('toggle-on');
  570. __main_header_all[i].style.display = '';
  571. }
  572. var sub_menu = __main_header_all[i].getElementsByClassName('sub-menu');
  573. for (var j = 0; j < sub_menu.length; j++) {
  574. sub_menu[j].style.display = '';
  575. }
  576. var child_menu = __main_header_all[i].getElementsByClassName('children');
  577. for (var k = 0; k < child_menu.length; k++) {
  578. child_menu[k].style.display = '';
  579. }
  580. var searchIcons = __main_header_all[i].getElementsByClassName('ast-search-menu-icon');
  581. for (var l = 0; l < searchIcons.length; l++) {
  582. searchIcons[l].classList.remove('ast-dropdown-active');
  583. searchIcons[l].style.display = '';
  584. }
  585. }
  586. }
  587. }, false);
  588. var get_browser = function () {
  589. var ua = navigator.userAgent,tem,M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
  590. if(/trident/i.test(M[1])) {
  591. tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
  592. return;
  593. }
  594. if( 'Chrome' === M[1] ) {
  595. tem = ua.match(/\bOPR|Edge\/(\d+)/)
  596. if(tem != null) {
  597. return;
  598. }
  599. }
  600. M = M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
  601. if((tem = ua.match(/version\/(\d+)/i)) != null) {
  602. M.splice(1,1,tem[1]);
  603. }
  604. if( 'Safari' === M[0] && M[1] < 11 ) {
  605. document.body.classList.add( "ast-safari-browser-less-than-11" );
  606. }
  607. }
  608. get_browser();
  609. /* Search Script */
  610. var SearchIcons = document.getElementsByClassName( 'astra-search-icon' );
  611. for (var i = 0; i < SearchIcons.length; i++) {
  612. SearchIcons[i].onclick = function(event) {
  613. if ( this.classList.contains( 'slide-search' ) ) {
  614. event.preventDefault();
  615. var sibling = this.parentNode.parentNode.parentNode.querySelector( '.ast-search-menu-icon' );
  616. if ( ! sibling.classList.contains( 'ast-dropdown-active' ) ) {
  617. sibling.classList.add( 'ast-dropdown-active' );
  618. sibling.querySelector( '.search-field' ).setAttribute('autocomplete','off');
  619. setTimeout(function() {
  620. sibling.querySelector( '.search-field' ).focus();
  621. },200);
  622. } else {
  623. var searchTerm = sibling.querySelector( '.search-field' ).value || '';
  624. if( '' !== searchTerm ) {
  625. sibling.querySelector( '.search-form' ).submit();
  626. }
  627. sibling.classList.remove( 'ast-dropdown-active' );
  628. }
  629. }
  630. }
  631. }
  632. /* Hide Dropdown on body click*/
  633. body.onclick = function( event ) {
  634. if ( typeof event.target.classList !== 'undefined' ) {
  635. if ( ! event.target.classList.contains( 'ast-search-menu-icon' ) && astraGetParents( event.target, '.ast-search-menu-icon' ).length === 0 && astraGetParents( event.target, '.ast-search-icon' ).length === 0 ) {
  636. var dropdownSearchWrap = document.getElementsByClassName( 'ast-search-menu-icon' );
  637. for (var i = 0; i < dropdownSearchWrap.length; i++) {
  638. dropdownSearchWrap[i].classList.remove( 'ast-dropdown-active' );
  639. }
  640. }
  641. }
  642. }
  643. /**
  644. * Navigation Keyboard Navigation.
  645. */
  646. function navigation_accessibility( containerMenu, containerButton ) {
  647. if ( ! containerMenu || ! containerButton ) {
  648. return;
  649. }
  650. var button = containerButton.getElementsByTagName( 'button' )[0];
  651. if ( 'undefined' === typeof button ) {
  652. button = containerButton.getElementsByTagName( 'a' )[0];
  653. if ( 'undefined' === typeof button ) {
  654. return;
  655. }
  656. }
  657. var menu = containerMenu.getElementsByTagName( 'ul' )[0];
  658. // Hide menu toggle button if menu is empty and return early.
  659. if ( 'undefined' === typeof menu ) {
  660. button.style.display = 'none';
  661. return;
  662. }
  663. menu.setAttribute( 'aria-expanded', 'false' );
  664. if ( -1 === menu.className.indexOf( 'nav-menu' ) ) {
  665. menu.className += ' nav-menu';
  666. }
  667. if ( 'off-canvas' === mobileHeaderType ) {
  668. var popupClose = document.getElementById( 'menu-toggle-close' );
  669. popupClose.onclick = function() {
  670. if ( -1 !== containerMenu.className.indexOf( 'toggled' ) ) {
  671. containerMenu.className = containerMenu.className.replace( ' toggled', '' );
  672. button.setAttribute( 'aria-expanded', 'false' );
  673. menu.setAttribute( 'aria-expanded', 'false' );
  674. } else {
  675. containerMenu.className += ' toggled';
  676. button.setAttribute( 'aria-expanded', 'true' );
  677. menu.setAttribute( 'aria-expanded', 'true' );
  678. }
  679. };
  680. }
  681. button.onclick = function() {
  682. if ( -1 !== containerMenu.className.indexOf( 'toggled' ) ) {
  683. containerMenu.className = containerMenu.className.replace( ' toggled', '' );
  684. button.setAttribute( 'aria-expanded', 'false' );
  685. menu.setAttribute( 'aria-expanded', 'false' );
  686. } else {
  687. containerMenu.className += ' toggled';
  688. button.setAttribute( 'aria-expanded', 'true' );
  689. menu.setAttribute( 'aria-expanded', 'true' );
  690. }
  691. };
  692. // Get all the link elements within the menu.
  693. var links = menu.getElementsByTagName( 'a' );
  694. var subMenus = menu.getElementsByTagName( 'ul' );
  695. // Set menu items with submenus to aria-haspopup="true".
  696. for ( var i = 0, len = subMenus.length; i < len; i++ ) {
  697. subMenus[i].parentNode.setAttribute( 'aria-haspopup', 'true' );
  698. }
  699. // Each time a menu link is focused or blurred, toggle focus.
  700. for ( i = 0, len = links.length; i < len; i++ ) {
  701. links[i].addEventListener( 'focus', toggleFocus, true );
  702. links[i].addEventListener( 'blur', toggleFocus, true );
  703. links[i].addEventListener( 'click', toggleClose, true );
  704. }
  705. }
  706. /**
  707. * Close the Toggle Menu on Click on hash (#) link.
  708. *
  709. * @since 1.3.2
  710. * @return void
  711. */
  712. function toggleClose( )
  713. {
  714. var self = this || '',
  715. hash = '#';
  716. if( self && ! self.classList.contains('astra-search-icon') && null === self.closest('.ast-builder-menu') ) {
  717. var link = new String( self );
  718. if( link.indexOf( hash ) !== -1 ) {
  719. var link_parent = self.parentNode;
  720. if ( body.classList.contains('ast-header-break-point') ) {
  721. if( ! ( document.querySelector('header.site-header').classList.contains('ast-builder-menu-toggle-link') && link_parent.classList.contains('menu-item-has-children') ) ) {
  722. /* Close Builder Header Menu */
  723. var builder_header_menu_toggle = document.querySelector( '.main-header-menu-toggle' );
  724. builder_header_menu_toggle.classList.remove( 'toggled' );
  725. var main_header_bar_navigation = document.querySelector( '.main-header-bar-navigation' );
  726. main_header_bar_navigation.classList.remove( 'toggle-on' );
  727. main_header_bar_navigation.style.display = 'none';
  728. astraTriggerEvent( document.querySelector('body'), 'astraMenuHashLinkClicked' );
  729. }
  730. } else {
  731. while ( -1 === self.className.indexOf( 'nav-menu' ) ) {
  732. // On li elements toggle the class .focus.
  733. if ( 'li' === self.tagName.toLowerCase() ) {
  734. if ( -1 !== self.className.indexOf( 'focus' ) ) {
  735. self.className = self.className.replace( ' focus', '' );
  736. }
  737. }
  738. self = self.parentElement;
  739. }
  740. }
  741. }
  742. }
  743. }
  744. /**
  745. * Sets or removes .focus class on an element on focus.
  746. */
  747. function toggleFocus() {
  748. var self = this;
  749. // Move up through the ancestors of the current link until we hit .nav-menu.
  750. while ( -1 === self.className.indexOf( 'navigation-accessibility' ) ) {
  751. // On li elements toggle the class .focus.
  752. if ( 'li' === self.tagName.toLowerCase() ) {
  753. self.classList.toggle('focus');
  754. }
  755. self = self.parentElement;
  756. }
  757. }
  758. /* Add class if mouse clicked and remove if tab pressed */
  759. if ( 'querySelector' in document && 'addEventListener' in window ) {
  760. body.addEventListener( 'mousedown', function() {
  761. body.classList.add( 'ast-mouse-clicked' );
  762. } );
  763. body.addEventListener( 'keydown', function() {
  764. body.classList.remove( 'ast-mouse-clicked' );
  765. } );
  766. }
  767. })();