PageSourceSearch

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

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

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.