PageSourceSearch

https://balboateam.com/wp-content/themes/enfold/js/avia-snippet-hamburger-menu.js?ver=5.6.2

js balboateam.com collected 2026-10-04 20:52:33 UTC 16,133 bytes, 573 lines download raw bytes

1/*
2 * Implements the hamburger menu behaviour
3 *
4 *
5 * @since 4.8		moved from avia.js to own file as some user request to customize this feature
6 */
7(function($)
8{
9    "use strict";
10
11    $(function()
12    {
13		$.avia_utilities = $.avia_utilities || {};
14
15		if( 'undefined' == typeof $.avia_utilities.isMobile )
16		{
17			if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) && 'ontouchstart' in document.documentElement )
18			{
19				$.avia_utilities.isMobile = true;
20			}
21			else
22			{
23				$.avia_utilities.isMobile = false;
24			}
25		}
26
27		//activates the hamburger mobile menu
28		avia_hamburger_menu();
29
30		$(window).trigger( 'resize' );
31
32	});
33
34	$.avia_utilities = $.avia_utilities || {};
35
36	function avia_hamburger_menu()
37	{
38		var header		= $('#header'),
39			header_main	= $('#main .av-logo-container'), //check if we got a top menu that is above the header
40			menu		= $('#avia-menu'),
41			burger_wrap = $('.av-burger-menu-main a'),
42			htmlEL  	= $('html').eq(0),
43			overlay		= $('<div class="av-burger-overlay"></div>'),
44			overlay_scroll	= $('<div class="av-burger-overlay-scroll"></div>').appendTo(overlay),
45			inner_overlay 	= $('<div class="av-burger-overlay-inner"></div>').appendTo(overlay_scroll),
46			bgColor 	  	= $('<div class="av-burger-overlay-bg"></div>').appendTo(overlay),
47			animating 	  	= false,
48			first_level	  	= {},
49			logo_container	= $('.av-logo-container .inner-container'),
50			menu_in_logo_container = logo_container.find('.main_menu'),
51			cloneFirst		= htmlEL.is('.html_av-submenu-display-click.html_av-submenu-clone, .html_av-submenu-display-hover.html_av-submenu-clone'),
52			menu_generated 	= false,
53			cloned_menu_cnt = 0;
54
55		if( ! htmlEL.hasClass( 'html_av-submenu-hidden' ) )
56		{
57			htmlEL.addClass( 'html_av-submenu-visible' );
58		}
59
60		/**
61		 * Check for alternate mobile menu
62		 */
63		var alternate = $('#avia_alternate_menu');
64		if( alternate.length > 0 )
65		{
66			menu = alternate;
67		}
68
69		var	set_list_container_height = function()
70			{
71				//necessary for ios since the height is usually not 100% but 100% - menu bar which can be requested by window.innerHeight
72				if($.avia_utilities.isMobile)
73				{
74					overlay_scroll.outerHeight(window.innerHeight);
75				}
76			},
77			create_list = function( items , append_to )
78			{
79				if( ! items )
80				{
81					return;
82				}
83
84				var list, link, current, subitems, megacolumns, sub_current, sub_current_list, new_li, new_ul;
85
86				items.each(function()
87				{
88					current  = $(this);
89					subitems = current.find(' > .sub-menu > li'); //find sublists of a regular defined menu
90					if( subitems.length == 0 )
91					{
92						subitems = current.find(' > .children > li'); //find sublists of a fallback menu
93					}
94					megacolumns = current.find( '.avia_mega_div > .sub-menu > li.menu-item' );
95
96					//	href = '#': we have a custom link that should not link to something - is also in use by megamenu for titles
97					var cur_menu = current.find('>a');
98					var clone_events = true;
99
100					if( cur_menu.length )
101					{
102						if( cur_menu.get(0).hash == '#' || 'undefined' == typeof cur_menu.attr('href') || cur_menu.attr('href') == '#' )
103						{
104							// eventhandler conflict 'click' by megamenu (returns false) - ignore all handlers
105							if( subitems.length > 0 || megacolumns.length > 0 )
106							{
107								clone_events = false;
108							}
109						}
110					}
111
112					link = cur_menu.clone(clone_events).attr('style','');
113
114						//	megamenus can have '' as url in top menu - allow click event in burger
115					if( 'undefined' == typeof cur_menu.attr('href') )
116					{
117						link.attr( 'href', '#' );
118					}
119
120					new_li = $('<li>').append( link );
121
122					//	Copy user set classes for menu items - these must not start with menu-item, page-item, page_item (used by default classes)
123					var cls = [];
124					if( 'undefined' != typeof current.attr('class') )
125					{
126						cls = current.attr('class').split(/\s+/);
127						$.each( cls, function( index, value ){
128										if( ( value.indexOf('menu-item') != 0 ) && ( value.indexOf('page-item') < 0 ) && ( value.indexOf('page_item') != 0 ) && ( value.indexOf('dropdown_ul') < 0 ) )
129										{
130											//	'current-menu-item' is also copied !!
131											new_li.addClass( value );
132										}
133										return true;
134									});
135					}
136
137					if( 'undefined' != typeof current.attr('id') && '' != current.attr('id') )
138					{
139						new_li.addClass(current.attr('id'));
140					}
141					else
142					{
143						//	fallback menu has no id -> try to find page id in class
144						$.each( cls, function( index, value ){
145										if( value.indexOf('page-item-') >= 0 )
146										{
147											new_li.addClass(value);
148											return false;
149										}
150								});
151					}
152
153					append_to.append(new_li);
154
155					if(subitems.length)
156					{
157						new_ul = $('<ul class="sub-menu">').appendTo(new_li);
158
159						if(cloneFirst && ( link.get(0).hash != '#' && link.attr('href') != '#' ))
160						{
161							new_li.clone(true).prependTo(new_ul);
162						}
163
164						new_li.addClass('av-width-submenu').find('>a').append('<span class="av-submenu-indicator">');
165
166						create_list( subitems , new_ul);
167					}
168					else if(megacolumns.length)	//if we got no normal sublists try megamenu columns and sublists
169					{
170						new_ul = $('<ul class="sub-menu">').appendTo(new_li);
171
172						if(cloneFirst && ( link.get(0).hash != '#' && link.attr('href') != '#' ))
173						{
174							new_li.clone(true).prependTo(new_ul);
175						}
176
177						megacolumns.each(function(iteration)
178						{
179							var megacolumn		= $(this),
180								mega_current  	= megacolumn.find( '> .sub-menu' ),		//	can be 0 if only a column is used without submenus
181								mega_title 		= megacolumn.find( '> .mega_menu_title' ),
182								mega_title_link = mega_title.find('a').attr('href') || "#",
183								current_megas 	= mega_current.length > 0 ? mega_current.find('>li') : null,
184								mega_title_set  = false,
185								mega_link 		= new_li.find('>a'),
186								hide_enty		= '';
187
188							//	ignore columns that have no actual link and no subitems
189							if( ( current_megas === null ) || ( current_megas.length == 0 ) )
190							{
191								if( mega_title_link == '#' )
192								{
193									hide_enty = ' style="display: none;"';
194								}
195							}
196
197							if(iteration == 0) new_li.addClass('av-width-submenu').find('>a').append('<span class="av-submenu-indicator">');
198
199							//if we got a title split up submenu items into multiple columns
200							if(mega_title.length && mega_title.text() != "")
201							{
202								mega_title_set  = true;
203
204								//if we are within the first iteration we got a new submenu, otherwise we start a new one
205								if(iteration > 0)
206								{
207									var check_li = new_li.parents('li').eq(0);
208
209									if(check_li.length) new_li = check_li;
210
211									new_ul = $('<ul class="sub-menu">').appendTo(new_li);
212								}
213
214
215								new_li = $('<li' + hide_enty + '>').appendTo(new_ul);
216								new_ul = $('<ul class="sub-menu">').appendTo(new_li);
217
218								$('<a href="'+mega_title_link+'"><span class="avia-bullet"></span><span class="avia-menu-text">' +mega_title.text()+ '</span></a>').insertBefore(new_ul);
219								mega_link = new_li.find('>a');
220
221								//	Clone if we have submenus
222								if(cloneFirst && ( mega_current.length > 0 ) && ( mega_link.length && mega_link.get(0).hash != '#' && mega_link.attr('href') != '#' ))
223								{
224									new_li.clone(true).addClass('av-cloned-title').prependTo(new_ul);
225								}
226
227							}
228
229								//	do not append av-submenu-indicator if no submenus (otherwise link action is blocked !!!)
230							if( mega_title_set && ( mega_current.length > 0 ) )
231							{
232								new_li.addClass('av-width-submenu').find('>a').append('<span class="av-submenu-indicator">');
233							}
234
235							create_list( current_megas , new_ul);
236						});
237
238					}
239
240				});
241
242				burger_wrap.trigger( 'avia_burger_list_created' );
243				return list;
244			};
245
246		var burger_ul, burger;
247
248		//prevent scrolling of outer window when scrolling inside
249		$('body').on( 'mousewheel DOMMouseScroll touchmove', '.av-burger-overlay-scroll', function (e)
250		{
251			var height = this.offsetHeight,
252				scrollHeight = this.scrollHeight,
253				direction = e.originalEvent.wheelDelta;
254
255			if(scrollHeight != this.clientHeight)
256			{
257				if( ( this.scrollTop >= (scrollHeight - height) && direction < 0) || (this.scrollTop <= 0 && direction > 0) )
258				{
259			      e.preventDefault();
260			    }
261		    }
262		    else
263		    {
264				e.preventDefault();
265		    }
266		});
267
268		//prevent scrolling for the rest of the screen
269		$(document).on( 'mousewheel DOMMouseScroll touchmove', '.av-burger-overlay-bg, .av-burger-overlay-active .av-burger-menu-main', function (e)
270		{
271			e.preventDefault();
272		});
273
274		//prevent scrolling on mobile devices
275		var touchPos = {};
276
277		$(document).on('touchstart', '.av-burger-overlay-scroll', function(e)
278		{
279			touchPos.Y = e.originalEvent.touches[0].clientY;
280		});
281
282		$(document).on('touchend', '.av-burger-overlay-scroll', function(e)
283		{
284			touchPos = {};
285		});
286
287		//prevent rubberband scrolling http://blog.christoffer.me/six-things-i-learnt-about-ios-safaris-rubber-band-scrolling/
288		$(document).on( 'touchmove', '.av-burger-overlay-scroll', function (e)
289		{
290			if(!touchPos.Y)
291			{
292				touchPos.Y = e.originalEvent.touches[0].clientY;
293			}
294
295			var	differenceY = e.originalEvent.touches[0].clientY - touchPos.Y,
296				element 	= this,
297				top 		= element.scrollTop,
298				totalScroll = element.scrollHeight,
299				currentScroll = top + element.offsetHeight,
300				direction	  = differenceY > 0 ? "up" : "down";
301
302			$('body').get(0).scrollTop = touchPos.body;
303
304	        if( top <= 0 )
305	        {
306	            if( direction == "up" )
307				{
308					e.preventDefault();
309				}
310
311	        }
312			else if( currentScroll >= totalScroll )
313	        {
314	            if( direction == "down" )
315				{
316					e.preventDefault();
317				}
318	        }
319		});
320
321		$(window).on( 'debouncedresize', function (e)
322		{
323			var close = true;
324
325			//	@since 4.8.3 we support portrait/landscape screens to switch mobile menu
326			if( $.avia_utilities.isMobile && htmlEL.hasClass( 'av-mobile-menu-switch-portrait' ) && htmlEL.hasClass( 'html_text_menu_active' ) )
327			{
328				var height = $( window ).height();
329				var width = $( window ).width();
330
331				if( width <= height )
332				{
333					//	in portrait mode we only need to remove added class
334					htmlEL.removeClass( 'html_burger_menu' );
335				}
336				else
337				{
338					//	in landscape mode
339					var switch_width = htmlEL.hasClass( 'html_mobile_menu_phone' ) ? 768 : 990;
340					if( height < switch_width )
341					{
342						htmlEL.addClass( 'html_burger_menu' );
343						close = false;
344					}
345					else
346					{
347						htmlEL.removeClass( 'html_burger_menu' );
348					}
349				}
350			}
351
352
353			//	close burger menu when returning to desktop
354			if( close && burger && burger.length )
355			{
356				if( ! burger_wrap.is(':visible') )
357				{
358					burger.filter(".is-active").parents('a').eq(0).trigger('click');
359				}
360			}
361
362			set_list_container_height();
363		});
364
365		//close overlay on overlay click
366		$('.html_av-overlay-side').on( 'click', '.av-burger-overlay-bg', function (e)
367		{
368			e.preventDefault();
369			burger.parents('a').eq(0).trigger('click');
370		});
371
372		 //close overlay when smooth scrollign begins
373		$(window).on('avia_smooth_scroll_start', function()
374		{
375			if(burger && burger.length)
376			{
377				burger.filter(".is-active").parents('a').eq(0).trigger('click');
378			}
379		});
380
381
382		//toogle hide/show for submenu items
383		$('.html_av-submenu-display-hover').on( 'mouseenter', '.av-width-submenu', function (e)
384		{
385			$(this).children("ul.sub-menu").slideDown('fast');
386		});
387
388		$('.html_av-submenu-display-hover').on( 'mouseleave', '.av-width-submenu', function (e)
389		{
390			$(this).children("ul.sub-menu").slideUp('fast');
391		});
392
393		$('.html_av-submenu-display-hover').on( 'click', '.av-width-submenu > a', function (e)
394		{
395			e.preventDefault();
396			e.stopImmediatePropagation();
397		});
398
399			//	for mobile we use same behaviour as submenu-display-click
400		$('.html_av-submenu-display-hover').on( 'touchstart', '.av-width-submenu > a', function (e)
401		{
402			var menu = $(this);
403			toggle_submenu( menu, e );
404		});
405
406
407		//toogle hide/show for submenu items
408		$('.html_av-submenu-display-click').on( 'click', '.av-width-submenu > a', function (e)
409		{
410			var menu = $(this);
411			toggle_submenu( menu, e );
412		});
413
414
415		//	close mobile menu if click on active menu item
416		$('.html_av-submenu-display-click, .html_av-submenu-visible').on( 'click', '.av-burger-overlay a', function (e)
417		{
418			var loc = window.location.href.match(/(^[^#]*)/)[0];
419			var cur = $(this).attr('href').match(/(^[^#]*)/)[0];
420
421			if( cur == loc )
422			{
423				e.preventDefault();
424				e.stopImmediatePropagation();
425
426				burger.parents('a').eq(0).trigger('click');
427				return false;
428			}
429
430			return true;
431		});
432
433
434		function toggle_submenu( menu, e )
435		{
436			e.preventDefault();
437			e.stopImmediatePropagation();
438
439			var parent  = menu.parents('li').eq(0);
440
441			parent.toggleClass('av-show-submenu');
442
443			if(parent.is('.av-show-submenu'))
444			{
445				parent.children("ul.sub-menu").slideDown('fast');
446			}
447			else
448			{
449				parent.children("ul.sub-menu").slideUp('fast');
450			}
451		};
452
453
454		(function normalize_layout()
455		{
456			//if we got the menu outside of the main menu container we need to add it to the container as well
457			if( menu_in_logo_container.length )
458			{
459				return;
460			}
461
462			var menu2 = $('#header .main_menu').clone(true),
463				ul = menu2.find('ul.av-main-nav'),
464				id = ul.attr('id');
465
466			if( 'string' == typeof id && '' != id.trim() )
467			{
468				ul.attr('id', id + '-' + cloned_menu_cnt++ );
469			}
470			menu2.find('.menu-item:not(.menu-item-avia-special)').remove();
471			menu2.insertAfter(logo_container.find('.logo').first());
472
473			//check if we got social icons and append it to the secondary menu
474			var social = $('#header .social_bookmarks').clone(true);
475			if( ! social.length )
476			{
477				social = $('.av-logo-container .social_bookmarks').clone(true);
478			}
479
480			if( social.length )
481			{
482				menu2.find('.avia-menu').addClass('av_menu_icon_beside');
483				menu2.append(social);
484			}
485
486			//re select the burger menu if we added a new one
487			burger_wrap = $('.av-burger-menu-main a');
488		}());
489
490
491
492		burger_wrap.on('click', function(e)
493		{
494			if( animating )
495			{
496				return;
497			}
498
499			burger = $(this).find('.av-hamburger'),
500			animating = true;
501
502			if(!menu_generated)
503			{
504				menu_generated = true;
505				burger.addClass("av-inserted-main-menu");
506
507				burger_ul = $('<ul>').attr({id:'av-burger-menu-ul', class:''});
508				var first_level_items = menu.find('> li:not(.menu-item-avia-special)'); //select all first level items that are not special items
509				var	list = create_list( first_level_items , burger_ul);
510
511				burger_ul.find('.noMobile').remove(); //remove any menu items with the class noMobile so user can filter manually if he wants
512				burger_ul.appendTo(inner_overlay);
513				first_level = inner_overlay.find('#av-burger-menu-ul > li');
514
515				if($.fn.avia_smoothscroll)
516				{
517					$('a[href*="#"]', overlay).avia_smoothscroll(overlay);
518				}
519			}
520
521			if(burger.is(".is-active"))
522			{
523				burger.removeClass("is-active");
524				htmlEL.removeClass("av-burger-overlay-active-delayed");
525
526				overlay.animate({opacity:0}, function()
527	    		{
528	    			overlay.css({display:'none'});
529					htmlEL.removeClass("av-burger-overlay-active");
530					animating = false;
531	    		});
532
533 			}
534			else
535			{
536				set_list_container_height();
537
538				var offsetTop = header_main.length ? header_main.outerHeight() + header_main.position().top : header.outerHeight() + header.position().top;
539
540				overlay.appendTo($(e.target).parents('.avia-menu'));
541
542				burger_ul.css({padding:( offsetTop ) + "px 0px"});
543
544				first_level.removeClass('av-active-burger-items');
545
546				burger.addClass("is-active");
547				htmlEL.addClass("av-burger-overlay-active");
548				overlay.css({display:'block'}).animate({opacity:1}, function()
549				{
550					animating = false;
551				});
552
553				setTimeout(function()
554				{
555					htmlEL.addClass("av-burger-overlay-active-delayed");
556				}, 100);
557
558				first_level.each(function(i)
559				{
560					var _self = $(this);
561					setTimeout(function()
562					{
563						_self.addClass('av-active-burger-items');
564					}, (i + 1) * 125);
565				});
566
567			}
568
569			e.preventDefault();
570		});
571	}
572
573})( jQuery );

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.