PageSourceSearch

https://www.werner.com/wp-content/plugins/responsive-menu-pro/v4.0.0/assets/js/rmp-menu.js?ver=4.3.0

js werner.com collected 2026-09-24 17:35:41 UTC 19,680 bytes, 634 lines download raw bytes

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

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.