1/** 2 * This file contain the scrips for menu frontend. 3 * @author ExpressTech System 4 * 5 * @since 4.0.0 6 */ 7 8jQuery( document ).ready( function( jQuery ) { 9 10 /** 11 * RmpMenu Class 12 * This RMP class is handling the frontend events and action on menu elements. 13 * @since 4.0.0 14 * @access public 15 * 16 * @class RmpMenu 17 */ 18 class RmpMenu { 19 20 /** 21 * This is constructor function which is initialize the elements and options. 22 * @access public 23 * @since 4.0.0 24 * @param {Array} options List of options. 25 */ 26 constructor( options ) { 27 RmpMenu.activeToggleClass = 'is-active'; 28 RmpMenu.openContainerClass = 'rmp-menu-open'; 29 RmpMenu.activeSubMenuArrowClass = 'rmp-menu-subarrow-active'; 30 RmpMenu.subMenuClass = '.rmp-submenu'; 31 32 this.options = options; 33 this.menuId = this.options['menu_id']; 34 this.trigger = '#rmp_menu_trigger-' + this.menuId; 35 36 this.isOpen = false; 37 38 this.container = '#rmp-container-' + this.menuId; 39 this.headerBar = '#rmp-header-bar-' + this.menuId; 40 this.menuWrap = 'ul#rmp-menu-'+ this.menuId; 41 this.pageOverlay = '#rmp-page-overlay-' + this.menuId; 42 this.subMenuArrow = '.rmp-menu-subarrow'; 43 this.wrapper = '.rmp-container'; 44 this.linkElement = '.rmp-menu-item-link'; 45 this.pageWrapper = this.options['page_wrapper']; 46 this.use_desktop_menu = this.options['use_desktop_menu']; 47 this.originalHeight = '', 48 this.animationSpeed = this.options['animation_speed'] * 1000; 49 this.hamburgerBreakpoint = this.options['tablet_breakpoint']; 50 this.subMenuTransitionTime = this.options['sub_menu_speed'] * 1000; 51 this.smoothScrollSpeed = this.options['smooth_scroll_speed'] * 1000; 52 53 if ( this.options['button_click_trigger'].length > 0 ) { 54 this.trigger = this.trigger +' , '+ this.options['button_click_trigger']; 55 } 56 57 this.init(); 58 } 59 60 /** 61 * Function to smooth scroll. 62 * @param {Event} event 63 */ 64 smoothScrollToLocation( event ) { 65 if(event.target.hash) { 66 jQuery('html, body').animate({ 67 scrollTop: jQuery(event.target.hash).offset().top 68 }, 500); 69 } 70 } 71 72 /** 73 * This function register the events and initiate the menu settings. 74 */ 75 init() { 76 const self = this; 77 78 // If option is enable from Toggle Button > others > Toggle menu on click. 79 if ( 'on' == this.options['button_trigger_type_click'] ) { 80 81 /** 82 * Register click event of trigger. 83 * @fires click 84 */ 85 jQuery( this.trigger ).on( 'click', function( e ) { 86 e.stopPropagation(); 87 self.triggerMenu(); 88 } ); 89 } 90 91 // If option is enable from Toggle Button > others > Toggle menu on hover. 92 if ( 'on' == this.options['button_trigger_type_hover'] ) { 93 94 /** 95 * Register mouseover event of trigger. 96 * @fires mouseover 97 */ 98 jQuery( this.trigger ).on( 'mouseover', function( e ) { 99 e.stopPropagation(); 100 self.triggerMenu(); 101 } ); 102 } 103 104 // Show/Hide sub menu item when click on item toggle. 105 jQuery( self.menuWrap ).find( self.subMenuArrow ).on( 'click', function( e ) { 106 e.preventDefault(); 107 e.stopPropagation(); 108 self.triggerSubArrow( this ); 109 }); 110 111 if ( 'on' == self.options['menu_close_on_body_click'] ) { 112 jQuery( document ).on( 'click', 'body', function ( e ) { 113 if ( jQuery( window ).width() < self.hamburgerBreakpoint ) { 114 if ( self.isOpen ) { 115 if ( jQuery( e.target ).closest( self.container ).length || jQuery( e.target ).closest( self.target ).length ) { 116 return; 117 } 118 } 119 self.closeMenu(); 120 } 121 }); 122 } 123 124 if ( 'on' == self.options['menu_close_on_scroll'] ) { 125 jQuery( window ).scroll( function( e ) { 126 if ( jQuery( window ).width() < self.hamburgerBreakpoint ) { 127 const menuSearchBox = jQuery( '.rmp-search-box' ); 128 129 // If focus is on search-box then menu will not be close. 130 if ( menuSearchBox && menuSearchBox.is( ':focus' ) ) { 131 return; 132 } else if ( self.isOpen ) { 133 self.closeMenu(); 134 } 135 } 136 } ); 137 } 138 139 /** 140 * This scripts enable the touch gestures. 141 */ 142 if ( self.options['enable_touch_gestures'] == 'on' ) { 143 144 // Close menu touch gestures. 145 let close_gesture = self.options['menu_appear_from']; 146 147 if ( self.options['menu_appear_from'] == 'top' ) { 148 close_gesture = 'up'; 149 } else if ( self.options['menu_appear_from'] == 'bottom' ) { 150 close_gesture = 'down'; 151 } 152 153 let pageScroll = "horizontal"; 154 if ( close_gesture == 'left' || close_gesture == 'right' ) { 155 pageScroll = "vertical"; 156 } 157
158 jQuery( self.container ).swipe( { 159 swipe:function(event, direction, distance, duration, fingerCount, fingerData) { 160 if( jQuery(window).width() < self.hamburgerBreakpoint ) { 161 if ( direction == close_gesture ) { 162 self.closeMenu(); 163 } 164 } 165 }, 166 threshold: 25, 167 allowPageScroll : pageScroll, 168 excludedElements: "button, input, select, textarea, a, .noSwipe, .rmp-search-box" 169 } ); 170 } 171 172 /** 173 * Close the menu when click on menu item link before load. 174 */ 175 if ( self.options['menu_close_on_link_click'] == 'on') { 176 177 jQuery( self.linkElement ).on( 'click', function(e) { 178 179 if( jQuery(window).width() < self.hamburgerBreakpoint ) { 180 e.preventDefault(); 181 182 // When close menu on parent clicks is on. 183 if ( self.options['menu_item_click_to_trigger_submenu'] == 'on' ) { 184 if( jQuery(this).is( '.rmp-menu-item-has-children > ' + self.linkElement ) ) { 185 return; 186 } 187 } 188 189 let _href = jQuery(this).attr('href'); 190 let _target = ( typeof jQuery(this).attr('target') ) == 'undefined' ? '_self' : jQuery(this).attr('target'); 191 192 if( self.isOpen ) { 193 if( jQuery(e.target).closest(this.subMenuArrow).length) { 194 return; 195 } 196 if( typeof _href != 'undefined' ) { 197 self.closeMenu(); 198 setTimeout(function() { 199 window.open( _href, _target); 200 }, self.animationSpeed); 201 } 202 } 203 } 204 }); 205 } 206 207 /** Multi screen slide effect */ 208 if ( self.options['use_slide_effect'] == 'on' ) { 209 jQuery( '.rmp-go-back' ).on( 'click', function() { 210 self.backUpSlide(this); 211 }); 212 } 213 214 //Show menu on page load section. 215 if ( 'on' == self.options['show_menu_on_page_load'] ) { 216 if ( jQuery(window).width() < self.hamburgerBreakpoint ) { 217 self.openMenu(); 218 } 219 } 220 221 // Keyboard shortcut menu open/close. 222 jQuery(document).on( 'keyup', function(e) { 223 if ( jQuery(window).width() < self.hamburgerBreakpoint ) { 224 let pressedKeyCode = e.keyCode.toString(); 225 let openKeyCodes = self.options['keyboard_shortcut_open_menu'];
226 let closeKeyCodes = self.options['keyboard_shortcut_close_menu']; 227 228 if ( jQuery.isArray( openKeyCodes ) && jQuery.inArray( pressedKeyCode, openKeyCodes ) !== -1 && ! self.isOpen ) { 229 self.openMenu(); 230 } else if ( jQuery.isArray( closeKeyCodes ) && jQuery.inArray( pressedKeyCode, closeKeyCodes ) !== -1 && self.isOpen ) { 231 self.closeMenu(); 232 } 233 } 234 }); 235 236 // Expand Sub items on Parent Item Click. 237 if ( 'on' == self.options['menu_item_click_to_trigger_submenu'] ) { 238 jQuery( '.rmp-menu-item-has-children > ' + self.linkElement ).on( 'click', function(e) { 239 if ( jQuery(window).width() < self.hamburgerBreakpoint ) { 240 e.preventDefault(); 241 self.triggerSubArrow( 242 jQuery(this).children( '.rmp-menu-subarrow' ).first() 243 ); 244 } 245 }); 246 } 247 248 //Smooth scrolling enable. 249 if ( self.options['smooth_scroll_on'] == 'on' ) { 250 jQuery( self.linkElement).on( 'click', function(e) { 251 self.smoothScrollToLocation(e); 252 }); 253 } 254 255 //Open submenu on click. 256 if ( self.options[ 'desktop_submenu_open_on_click' ] == 'on' ) { 257 258 jQuery( self.menuWrap + ' li.rmp-menu-item-has-children a.rmp-menu-item-link' ).on( 'click', function( e ) { 259 260 if ( jQuery(window).width() > self.hamburgerBreakpoint ) { 261 e.stopPropagation(); 262 e.preventDefault(); 263 e.stopImmediatePropagation(); 264 var submenu = jQuery(this).siblings('.rmp-submenu'); 265 if ( ! submenu.length || jQuery(this).attr( 'data-click') ) { 266 window.location = this.href; 267 } else { 268 jQuery(this).attr( 'data-click', true ); 269 submenu.addClass( 'rmp-submenu-animate-on' ); 270 submenu.show(); 271 return false; 272 } 273 } 274 275 }); 276 } 277 278 /* Desktop menu : Hide on scroll down / Show on scroll Up */ 279 if ( self.options['use_desktop_menu'] == 'on' && self.options['desktop_menu_hide_and_show'] == 'on' ) { 280 var lastScrollTop, currentScrollPos = 0; 281 var desktop_header = jQuery(self.container); 282 283 if ( self.options['use_header_bar'] == 'on') { 284 desktop_header = jQuery(self.headerBar); 285 } 286 287 jQuery( window ).scroll( function () { 288 289 if ( jQuery(window).width() > self.hamburgerBreakpoint ) { 290 var desktop_header_height = desktop_header.height(); 291 currentScrollPos = jQuery(window).scrollTop(); 292 if ( lastScrollTop < currentScrollPos && currentScrollPos > desktop_header_height) { 293 desktop_header.fadeOut(100); 294 desktop_header.css({ 295 'transform' : 'translateY( -'+ desktop_header_height +'px )' 296 }); 297 } else { 298 desktop_header.fadeIn(100); 299 desktop_header.css( { 'transform' : '' } ); 300 } 301 302 lastScrollTop = currentScrollPos; 303 } 304 }); 305 } 306 307 // Change the color of header on scrolling. 308 if ( 'on' == self.options['use_header_bar'] && 'on' == self.options['header_bar_scroll_enable'] ) { 309 jQuery( window ).scroll( function () { 310 const headerBar = jQuery( self.headerBar ); 311 if ( jQuery(window).scrollTop() > headerBar.height() ) { 312 headerBar.addClass('header-scolling-bg-color'); 313 } else { 314 headerBar.removeClass('header-scolling-bg-color'); 315 } 316 }); 317 } 318 319 } 320 /** 321 * Set push translate for toggle and page wrapper. 322 */ 323 setWrapperTranslate() { 324 325 let translate,translateContainer; 326 switch( this.options['menu_appear_from'] ) { 327 case 'left': 328 translate = 'translateX(' + this.menuWidth() + 'px)'; 329 translateContainer = 'translateX(-' + this.menuWidth() + 'px)'; 330 break; 331 case 'right': 332 translate = 'translateX(-' + this.menuWidth() + 'px)'; 333 translateContainer = 'translateX(' + this.menuWidth() + 'px)'; 334 break; 335 case 'top': 336 translate = 'translateY(' + this.wrapperHeight() + 'px)'; 337 translateContainer = 'translateY(-' + this.menuHeight() + 'px)'; 338 break; 339 case 'bottom': 340 translate = 'translateY(-' + this.menuHeight() + 'px)'; 341 translateContainer = 'translateY(' + this.menuHeight() + 'px)'; 342 break; 343 } 344 345 if ( this.options['animation_type'] == 'push' ) { 346 347 jQuery(this.pageWrapper).css( { 'transform':translate } ); 348 349 //If push Wrapper has body element then handle menu position. 350 if ( 'body' == this.pageWrapper ) { 351 jQuery( this.container ).css( { 'transform' : translateContainer } ); 352 } 353 } 354 355 if ( this.options['button_push_with_animation'] == 'on' ) { 356 jQuery( this.trigger ).css( { 'transform' : translate } ); 357 } 358 359 } 360 361 /** 362 * Clear push translate on button and page wrapper. 363 */ 364 clearWrapperTranslate() { 365 366 if ( this.options['animation_type'] == 'push' ) { 367 jQuery(this.pageWrapper).css( { 'transform' : '' } ); 368 } 369 370 if ( this.options['button_push_with_animation'] == 'on' ) { 371 jQuery( this.trigger ).css( { 'transform' : '' } ); 372 } 373 } 374 375 /** 376 * Function to fadeIn the hamburger menu container. 377 */ 378 fadeMenuIn() { 379 jQuery(this.container).fadeIn(this.animationSpeed); 380 } 381 382 /** 383 * Function to fadeOut the hamburger menu container. 384 */ 385 fadeMenuOut() { 386 jQuery(this.container) 387 .fadeOut(this.animationSpeed, function() { 388 jQuery(this).css('display', ''); 389 }); 390 } 391 392 /** 393 * Function is use to open the hamburger menu. 394 * 395 * @since 4.0.0 396 */ 397 openMenu() { 398 var self = this; 399 jQuery(this.trigger).addClass(RmpMenu.activeToggleClass); 400 jQuery(this.container).addClass(RmpMenu.openContainerClass); 401 402 if ( this.options['menu_overlay'] == 'on') { 403 jQuery(this.pageOverlay).addClass(RmpMenu.activeToggleClass); 404 } 405 406 //this.pushMenuTrigger(); 407 408 if ( this.options['animation_type'] == 'fade'){ 409 this.fadeMenuIn(); 410 } else { 411 this.setWrapperTranslate(); 412 } 413 414 /** 415 * Fading items from slid. 416 */ 417 if ( self.options['fade_submenus'] == 'on' ) { 418 419 jQuery( ".rmp-menu > li" ).each( function(index) { 420 jQuery(this).show(); 421 jQuery(this).animate( { opacity: 0 }, 0 ); 422 423 if ( self.options['fade_submenus_side'] == 'left' ) { 424 jQuery(this).animate( { 'margin-left':'-150px' } ,0 ); 425 } 426 427 if ( self.options['fade_submenus_side'] == 'right' ) { 428 jQuery(this).animate({'margin-left':'150px'},0); 429 } 430 431 jQuery( this ).delay( self.options[ 'fade_submenus_delay' ] * index ).animate({ 432 'margin-left': "0", 433 'opacity': 1 434 }, self.options['fade_submenus_delay'] ); 435 }); 436 } 437 438 439 if ( self.options['use_slide_effect'] == 'on' ) { 440 if( jQuery(window).width() <= self.hamburgerBreakpoint ) {
441 jQuery( self.menuWrap ).promise().done( function () { 442 self.originalHeight = jQuery( self.menuWrap ).height(); 443 jQuery( self.menuWrap ).css({'height': self.originalHeight}); 444 }); 445 } 446 } 447 448 // Disable the background scrolling. 449 if ( 'on' == self.options['menu_disable_scrolling'] ) { 450 bodyScrollLock.disableBodyScroll( 451 jQuery(this.container), 452 {reserveScrollBarGap: true} 453 ); 454 } 455 456 this.isOpen = true; 457 } 458 459 /** 460 * Function is use to close the hamburger menu. 461 * 462 * @since 4.0.0 463 */ 464 closeMenu() { 465 jQuery(this.trigger).removeClass(RmpMenu.activeToggleClass); 466 jQuery(this.container).removeClass(RmpMenu.openContainerClass); 467 468 if ( this.options['menu_overlay'] == 'on') { 469 jQuery(this.pageOverlay).removeClass(RmpMenu.activeToggleClass); 470 } 471 472 if ( this.options['animation_type'] == 'fade') { 473 this.fadeMenuOut(); 474 } else { 475 this.clearWrapperTranslate(); 476 } 477 478 // Release the blocking scrolling. 479 if ( 'on' == this.options['menu_disable_scrolling'] ) { 480 bodyScrollLock.clearAllBodyScrollLocks(); 481 } 482 483 this.isOpen = false; 484 } 485 486 /** 487 * Function is responsible for checking the menu is open or close. 488 * 489 * @since 4.0.0 490 * @param {Event} e 491 */ 492 triggerMenu() { 493 this.isOpen ? this.closeMenu() : this.openMenu(); 494 } 495 496 triggerSubArrow( subArrow ) { 497 var self = this; 498 var sub_menu = jQuery( subArrow ).parent().siblings( RmpMenu.subMenuClass ); 499 500 501 // Use sliding effect. 502 if ( self.options['use_slide_effect'] == 'on' ) { 503 if( jQuery(window).width() <= self.hamburgerBreakpoint ) { 504 jQuery(self.container).find( '.rmp-submenu-open').removeClass('rmp-submenu-open'); 505 sub_menu.addClass('rmp-submenu-open'); 506 sub_menu.parentsUntil(self.menuWrap).addClass( 'rmp-submenu-open' );
507 let current_depth = jQuery(subArrow).parents('.rmp-submenu').data('depth'); 508 current_depth = typeof current_depth == 'undefined' ? 1 : current_depth; 509 let translation_amount = current_depth * 100; 510 jQuery(self.menuWrap).css({'transform': 'translateX(-' + translation_amount + '%)'}); 511 jQuery(self.menuWrap).css({'height': sub_menu.height() + 'px'}); 512 } 513 } else { 514 515 //Accordion animation. 516 if ( self.options['accordion_animation'] == 'on' ) { 517 // Get Top Most Parent and the siblings. 518 var top_siblings = sub_menu.parents('.rmp-menu-item-has-children').last().siblings('.rmp-menu-item-has-children'); 519 var first_siblings = sub_menu.parents('.rmp-menu-item-has-children').first().siblings('.rmp-menu-item-has-children'); 520 521 // Close up just the top level parents to key the rest as it was. 522 top_siblings.children('.rmp-submenu').slideUp(self.subMenuTransitionTime, 'linear').removeClass('rmp-submenu-open'); 523 524 // Set each parent arrow to inactive. 525 top_siblings.each(function() { 526 jQuery(this).find(self.subMenuArrow).first().html(self.options['inactive_toggle_contents']); 527 jQuery(this).find(self.subMenuArrow).first().removeClass(RmpMenu.activeSubMenuArrowClass); 528 }); 529 530 // Now Repeat for the current item siblings. 531 first_siblings.children('.rmp-submenu').slideUp(self.subMenuTransitionTime, 'linear').removeClass('rmp-submenu-open'); 532 first_siblings.each(function() { 533 jQuery(this).find(self.subMenuArrow).first().html(self.options['inactive_toggle_contents']); 534 jQuery(this).find(self.subMenuArrow).first().removeClass(RmpMenu.activeSubMenuArrowClass); 535 }); 536 } 537 538 // Active sub menu as default behavior. 539 if( sub_menu.hasClass('rmp-submenu-open') ) { 540 sub_menu.slideUp(self.subMenuTransitionTime, 'linear',function() { 541 jQuery(this).css( 'display', '' ); 542 } ).removeClass('rmp-submenu-open'); 543 jQuery( subArrow ).html( self.options['inactive_toggle_contents'] ); 544 jQuery( subArrow ).removeClass(RmpMenu.activeSubMenuArrowClass); 545 } else { 546 sub_menu.slideDown(self.subMenuTransitionTime, 'linear').addClass( 'rmp-submenu-open' ); 547 jQuery( subArrow ).html(self.options['active_toggle_contents'] ); 548 jQuery( subArrow ).addClass(RmpMenu.activeSubMenuArrowClass); 549 } 550 } 551 } 552 553 /** 554 * Function to add tranform style on trigger. 555 * 556 * @version 4.0.0 557 * 558 * @param {Event} e Event object. 559 */ 560 pushMenuTrigger( e ) { 561 if ( 'on' == this.options['button_push_with_animation'] ) { 562 jQuery( this.trigger ).css( { 'transform' : this.menuWidth() } ); 563 } 564 } 565 566 /** 567 * Returns the height of container. 568 * 569 * @version 4.0.0 570 * 571 * @return Number 572 */ 573 menuHeight() { 574 return jQuery( this.container ).height(); 575 } 576 577 /** 578 * Returns the width of the container. 579 * 580 * @version 4.0.0 581 * 582 * @return Number 583 */ 584 menuWidth() { 585 return jQuery( this.container ).width(); 586 } 587 588 wrapperHeight() { 589 return jQuery( this.wrapper ).height(); 590 } 591 592 backUpSlide( backButton ) { 593 let translateTo = parseInt( jQuery( this.menuWrap )[0].style.transform.replace( /^\D+/g, '' ) ) - 100; 594 jQuery( this.menuWrap ).css( { 'transform': 'translateX(-' + translateTo + '%)' } ); 595 let previousSubmenuHeight = jQuery( backButton ).parent( 'ul' ).parent( 'li' ).parent( '.rmp-submenu' ).height(); 596 if ( ! previousSubmenuHeight ) { 597 jQuery( this.menuWrap ).css( { 'height': this.originalHeight } ); 598 } else { 599 jQuery( this.menuWrap + this.menuId ).css( { 'height': previousSubmenuHeight + 'px' } ); 600 } 601 } 602 } 603 604 /** 605 * Create multiple instance of menu and pass the options. 606 * 607 * @version 4.0.0 608 */ 609 for ( let index = 0; index < rmp_menu.menu.length; index++ ) { 610 let rmp = new RmpMenu( rmp_menu.menu[index] ); 611 } 612 613 // Twenty twenty theme support. 614 if ( typeof twentytwenty != 'undefined' ) { 615 jQuery( 'header#site-header' ).find('ul.primary-menu').removeClass('primary-menu'); 616 } 617 618} );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.