PageSourceSearch

https://olgaplickova.cz/wp-content/themes/mioweb3/library/visualeditor/js/front_menu.js?ver=1791338428

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

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.