PageSourceSearch

https://supportday.cz/wp-content/themes/mioweb/modules/visualeditor/js/front_menu.js?ver=1

js supportday.cz collected 2026-10-08 05:15:20 UTC 10,502 bytes, 379 lines download raw bytes

1/* global jQuery */
2( function( $ ){
3
4	var FrontMenu = {
5
6		init: function() {
7
8			this.header_wrap = $( '#header' );
9			this.header_wrap_in = this.header_wrap.find( '#header_in' );
10			this.menu_wrap = this.header_wrap.find( '#site_header_nav' );
11			this.top_level_menu_items = this.menu_wrap.find( '.menu > .menu-item' );
12			this.items_with_submenu = this.menu_wrap.find( '.menu-item-has-children' );
13			this.items_with_submenu_anchors = this.items_with_submenu.children( 'span' );
14			this.menu_on_the_right = this.header_wrap.find( '#header_in' ).hasClass( 'fix_width header_in_s1' );
15			this.logo = this.header_wrap.find( '#site_title' );
16			this.submenus = this.top_level_menu_items.find( '.sub-menu' );
17			this.mobile_nav_button = $( '#mobile_nav' );
18
19			this.tolerance_margin = 10;
20			this.placeholders_added = false;
21			this.is_mobile_menu = false;
22			this.is_full_width_menu = this.header_wrap.hasClass( 'header_in_s2' );
23
24			this.bindEvents();
25
26		},
27
28		bindEvents: function() {
29
30			this.checkForMobileMenu() ;//DOM ready
31			$( window ).load( $.proxy( this.checkForMobileMenu, this ) );
32			$( window ).on( 'resize', $.proxy( this.checkForMobileMenu, this ) );
33
34
35		},
36
37		checkForMobileMenu: function() {
38
39			var available_width = 0,
40				all_items_width = 0;
41
42			this.header_wrap.removeClass( 'is-mobile_menu' );
43			this.is_mobile_menu = false;
44
45			for( var i = 0, length = this.top_level_menu_items.length; i < length; i++ ) {
46				all_items_width = all_items_width + this.top_level_menu_items.eq( i ).outerWidth( true );
47			}
48
49			if( this.menu_on_the_right ) {
50				available_width = this.header_wrap_in.width() - this.logo.outerWidth();
51			} else {
52				available_width = this.menu_wrap.width();
53			}
54
55			if( ( available_width - this.tolerance_margin ) <= all_items_width ) {
56				//menu has to wrap to mobile
57				this.header_wrap.addClass( 'is-mobile_menu' );
58				this.is_mobile_menu = true;
59			}
60
61
62			//Bind specific events
63			this.unbindDesktopEvents();
64			this.unbindMobileEvents();
65
66			if( this.is_mobile_menu ) {
67				this.bindMobileEvents();
68			} else {
69				this.bindDesktopEvents();
70			}
71
72		},
73
74		bindDesktopEvents: function() {
75
76			this.checkForOverflowedSubmenus();
77			$( window ).on( 'load.mio_menu__desktop__checkoverflow', $.proxy( this.checkForOverflowedSubmenus, this ) );
78			$( window ).on( 'resize.mio_menu__desktop__checkoverflow', $.proxy( this.checkForOverflowedSubmenus, this ) );
79
80			//Hovers
81			var t = this;
82			this.items_with_submenu.on( 'mouseenter.mio_menu__desktop__hovers', function(){
83				t.showHideSubmenu( $( this ), 'show' );
84			} );
85			this.items_with_submenu.on( 'mouseleave.mio_menu__desktop__hovers', function(){
86				t.showHideSubmenu( $( this ), 'hide' );
87			} );
88
89			//Click on parent item
90			this.items_with_submenu_anchors.on( 'touchstart.mio_menu__desktop__taps', function(){
91				var el = $( this );
92				el.data( 'scrolling', false );
93			} );
94			this.items_with_submenu_anchors.on( 'touchmove.mio_menu__desktop__taps', function(){
95				var el = $( this );
96				el.data( 'scrolling', true );
97			} );
98			this.items_with_submenu_anchors.on( 'touchend.mio__front_menu__open_submenu', function( evt ){
99				var el = $( this );
100				if( el.data( 'scrolling' ) !== true ){
101					t.checkForTap( evt, el );
102				}
103				el.data( 'scrolling', false );
104			} );
105
106		},
107
108		unbindDesktopEvents: function() {
109
110			$( window ).off( 'load.mio_menu__desktop__checkoverflow' );
111			$( window ).off( 'resize.mio_menu__desktop__checkoverflow' );
112
113			//Hovers
114			this.items_with_submenu.off( 'mouseenter.mio_menu__desktop__hovers' );
115			this.items_with_submenu.off( 'mouseleave.mio_menu__desktop__hovers' );
116
117			//Click on parent item
118			this.items_with_submenu_anchors.off( 'touchstart.mio_menu__desktop__taps' );
119			this.items_with_submenu_anchors.off( 'touchmove.mio_menu__desktop__taps' );
120			this.items_with_submenu_anchors.off( 'touchend.mio__front_menu__open_submenu' );
121
122			//Runtimes
123			this.items_with_submenu_anchors.off( 'click.mio_menu__desktop__prevent_click' );
124			$( document ).off( 'click.mio__front_menu__close_submenu' );
125
126
127		},
128
129		bindMobileEvents: function() {
130
131			var t = this;
132			this.items_with_submenu_anchors.on( 'click.mio_menu__mobile__toggle_submenu', function( evt ){
133				evt.preventDefault();
134				t.showHideSubmenu( $( this ).parent(), 'toggle', true );
135			} );
136
137			this.mobile_nav_button.on( 'click.mio_menu__mobile__toggle_menu', function( evt ){
138				evt.preventDefault();
139				t.toggleMobileMenu();
140			} );
141
142		},
143
144		unbindMobileEvents: function() {
145
146			this.items_with_submenu_anchors.off( 'click.mio_menu__mobile__toggle_submenu' );
147			this.mobile_nav_button.off( 'click.mio_menu__mobile__toggle_menu' );
148
149		},
150
151		checkForOverflowedSubmenus: function() {
152
153
154			var body = $( 'html' );
155			body.css( 'overflow-x', '' );
156
157			var document_width = $( window ).width();
158
159			this.items_with_submenu.removeClass( 'is-submenu_on_left' );
160
161			this.submenus.show();
162
163			var t = this;
164			this.submenus.each( function(){
165				var submenu = $( this );
166				var adjusted = false;
167
168				var is_top_level_on_s2 = ( t.is_full_width_menu && submenu.parents( '.sub-menu' ).length === 0 );
169
170				if( is_top_level_on_s2 ) { //Only on top-level menus on s2 header style
171					submenu.css({
172						'left': '50%',
173						'right': '',
174						'margin-left': ''
175					});
176				} else {
177					submenu.css({
178						'left': '',
179						'right': ''
180					});
181				}
182
183				var submenu_right_side_offset = ( submenu.offset().left + submenu.outerWidth( true ) );
184
185				if( submenu_right_side_offset > document_width ) {
186					adjusted = true;
187
188					var is_third_level = ( $( this ).parents( '.sub-menu' ).length > 0 );
189
190					if( is_third_level ) {
191						$( this ).parent().addClass( 'is-submenu_on_left' );
192					}
193
194					if( is_top_level_on_s2 ) {
195						submenu.css({
196							'margin-left': ( document_width - submenu_right_side_offset )
197						});
198					} else {
199						submenu.css({
200							'left': 'auto',
201							'right': ( is_third_level ) ? '100%' : '0'
202						});
203					}
204
205				}
206
207				//Additional check for S2 menus on left side
208				if( is_top_level_on_s2 && adjusted === false ) {
209
210					var submenu_left_offset = submenu.offset().left,
211						menu_left_offset = t.menu_wrap.offset().left;
212
213
214					if( submenu_left_offset < menu_left_offset ) {
215						submenu.css( {
216							'margin-left': ( menu_left_offset - submenu_left_offset )
217						} );
218					}
219
220				}
221
222			} );
223
224			this.submenus.hide();
225
226			body.css( 'overflow-x', 'hidden' );
227
228		},
229
230		/*
231		 * @param action 'show'|'hide'|'toggle'
232		 */
233		showHideSubmenu: function( element, action, slide ) {
234			slide = typeof slide === 'undefined' ? false : true;
235
236			if( action === 'toggle' ) {
237				action = ( element.data( 'mio_hovering' ) === true ) ? 'hide' : 'show'; //If submenu is open, close it and vice versa
238			}
239
240			element.data( 'mio_hovering', ( action === 'show' ) );
241
242			var submenu = element.children( '.sub-menu' );
243			var velocity_action;
244			if( action === 'show' ) {
245				velocity_action = ( slide ) ? 'slideDown' : 'fadeIn';
246			} else {
247				velocity_action = ( slide ) ? 'slideUp' : 'fadeOut';
248			}
249      
250      element.children( 'span' ).toggleClass('opened');
251
252
253			var complete_function = ( action === 'show' ) ? null : function( el ) {
254				$( el ).css( 'opacity', '' );
255			};
256
257			submenu.velocity( 'stop' ).velocity( velocity_action, { duration: 200, complete: complete_function } );
258
259		},
260
261
262		/*
263		 * If we detect click on parent and submenu is not visible at this time - it was probably tap and we want just to show submenu
264		 */
265		checkForTap: function( evt, anchor_element ) {
266
267			//Prevent clicks legacy event
268			evt.preventDefault();
269			anchor_element.on( 'click.mio_menu__desktop__prevent_click', function( evt ){
270				evt.preventDefault();
271			} );
272
273			//Add placeholder items
274			if( this.placeholders_added === false ) {
275				this.addPlaceholderItems();
276			}
277
278			//Close all other parent submenus - only on desktop menu
279			if( this.is_mobile_menu === false ) {
280				this.closeAllOpenSubmenus( anchor_element.parent() );
281			}
282
283			//Open submenu
284			this.showHideSubmenu( anchor_element.parent(), 'show' );
285
286
287			//Close on tap outside menu
288			this.bindCloseSubmenuOnClickOutside( anchor_element.parent() );
289
290		},
291
292		bindCloseSubmenuOnClickOutside: function( submenu_parent ) {
293
294			this.items_with_submenu.on( 'click', function( evt ){
295				evt.stopPropagation();
296			} );
297
298			var t = this;
299			$( document ).on( 'click.mio__front_menu__close_submenu', function(){
300				t.showHideSubmenu( submenu_parent, 'hide' );
301				$( document ).off( 'click.mio__front_menu__close_submenu' );
302			} );
303
304		},
305
306		/*
307		 * @param jQuery li-element of currently clicked submenu - it's parent submenu won't be closed
308		 */
309		closeAllOpenSubmenus: function( clicked_parent ) {
310			clicked_parent = clicked_parent || false;
311
312			var open_menus = this.items_with_submenu.filter( function(){
313				var submenu_parent = $( this );
314				if( clicked_parent !== false ) {
315					if( submenu_parent.is( clicked_parent.parents( 'ul:first' ).parent( 'li' ) ) ) return false; //We don't want to close parent submenu_wrapper of current submenu wrapper
316				}
317				return submenu_parent.data( 'mio_hovering' ); //Mio hovering is also indicating, if current menu is open
318			} );
319
320			var t = this;
321			open_menus.each( function(){
322				t.showHideSubmenu( $( this ), 'hide' );
323			} );
324		},
325
326		addPlaceholderItems: function() {
327
328			this.items_with_submenu.each( function(){
329				var parent = $( this ),
330					new_element = parent.clone().empty().removeClass( 'menu-item-has-children' );
331				new_element.append( parent.clone().children( 'a' ) );
332				parent.find('.sub-menu:first').prepend( new_element );
333			} );
334
335			this.checkForOverflowedSubmenus();
336
337			this.placeholders_added = true;
338
339		},
340
341		toggleMobileMenu: function() {
342
343			var menu_open = this.menu_wrap.is( ':visible' ),
344				velocity_action = ( menu_open ) ? 'slideUp' : 'slideDown',
345				complete_function = ( menu_open ) ? function( el ){
346					$( el ).attr( 'style', '' );
347				} : false;
348
349			this.menu_wrap.velocity( 'stop' ).velocity( velocity_action, { duration: 500, complete: complete_function } );
350      
351      $('#mobile_nav span').hide();
352      
353      if(menu_open) {
354          $('.mobile_nav_menu').show();
355      } else {
356          $('.mobile_nav_close').show();
357      }
358
359		}
360
361
362
363	};
364
365
366	//Dom ready
367	$( function(){
368		FrontMenu.init();
369	} );
370
371	//Menu changed in editor
372	$( document ).on( 'mio_editor__replaced_menu', function() {
373		FrontMenu.unbindDesktopEvents();
374		FrontMenu.unbindMobileEvents();
375		FrontMenu.init();
376	} );
377
378
379} )( 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.