PageSourceSearch

https://www.resimliroman.net/layouts/xet_pilates_wity/js/mlmenu.js?t=1764555586

js resimliroman.net collected 2026-09-25 01:36:54 UTC 10,148 bytes, 335 lines download raw bytes

1(function (window) {
2
3	'use strict';
4
5	var support = {
6			animations: Modernizr.cssanimations
7		},
8		animEndEventNames = {
9			'WebkitAnimation': 'webkitAnimationEnd',
10			'OAnimation': 'oAnimationEnd',
11			'msAnimation': 'MSAnimationEnd',
12			'animation': 'animationend'
13		},
14		animEndEventName = animEndEventNames[Modernizr.prefixed('animation')],
15		onEndAnimation = function (el, callback) {
16			var onEndCallbackFn = function (ev) {
17				if (support.animations) {
18					if (ev.target != this) return;
19					this.removeEventListener(animEndEventName, onEndCallbackFn);
20				}
21				if (callback && typeof callback === 'function') {
22					callback.call();
23				}
24			};
25			if (support.animations) {
26				el.addEventListener(animEndEventName, onEndCallbackFn);
27			} else {
28				onEndCallbackFn();
29			}
30		};
31
32	function extend(a, b) {
33		for (var key in b) {
34			if (b.hasOwnProperty(key)) {
35				a[key] = b[key];
36			}
37		}
38		return a;
39	}
40
41	function MLMenu(el, options) {
42		this.el = el;
43		this.options = extend({}, this.options);
44		extend(this.options, options);
45
46		// the menus (<ul>´s)
47		this.menus = [].slice.call(this.el.querySelectorAll('.menu__level'));
48		// index of current menu
49		this.current = 0;
50
51		this._init();
52	}
53
54	MLMenu.prototype.options = {
55		// show breadcrumbs
56		breadcrumbsCtrl: true,
57		// initial breadcrumb text
58		initialBreadcrumb: 'all',
59		// show back button
60		backCtrl: true,
61		// delay between each menu item sliding animation
62		itemsDelayInterval: 60,
63		// direction
64		direction: 'r2l',
65		// callback: item that doesn´t have a submenu gets clicked
66		// onItemClick([event], [inner HTML of the clicked item])
67		onItemClick: function (ev, itemName) {
68			return false;
69		}
70	};
71
72	MLMenu.prototype._init = function () {
73		// iterate the existing menus and create an array of menus, more specifically an array of objects where each one holds the info of each menu element and its menu items
74		this.menusArr = [];
75		var self = this;
76		this.menus.forEach(function (menuEl, pos) {
77			var menu = {
78				menuEl: menuEl,
79				menuItems: [].slice.call(menuEl.querySelectorAll('.menu__item'))
80			};
81			self.menusArr.push(menu);
82
83			// set current menu class
84			if (pos === self.current) {
85				classie.add(menuEl, 'menu__level--current');
86			}
87		});
88
89		// create back button
90		if (this.options.backCtrl) {
91			this.backCtrl = document.createElement('button');
92			this.backCtrl.className = 'menu__back menu__back--hidden';
93			this.backCtrl.setAttribute('aria-label', 'Go back');
94			this.backCtrl.innerHTML = '<i class="xi-arrow-left"></i>';
95			this.el.insertBefore(this.backCtrl, this.el.firstChild);
96		}
97
98
99		// create breadcrumbs
100		if (self.options.breadcrumbsCtrl) {
101			this.breadcrumbsCtrl = document.createElement('nav');
102			this.breadcrumbsCtrl.className = 'menu__breadcrumbs';
103			this.el.insertBefore(this.breadcrumbsCtrl, this.el.firstChild);
104			// add initial breadcrumb
105			this._addBreadcrumb(0);
106		}
107
108		// event binding
109		this._initEvents();
110	};
111
112	MLMenu.prototype._initEvents = function () {
113		var self = this;
114
115		for (var i = 0, len = this.menusArr.length; i < len; ++i) {
116			this.menusArr[i].menuItems.forEach(function (item, pos) {
117				item.querySelector('a').addEventListener('click', function (ev) {
118					var submenu = ev.target.getAttribute('data-submenu'),
119						itemName = ev.target.innerHTML,
120						subMenuEl = self.el.querySelector('ul[data-menu="' + submenu + '"]');
121
122					// check if there's a sub menu for this item
123					if (submenu && subMenuEl) {
124						ev.preventDefault();
125						// open it
126						self._openSubMenu(subMenuEl, pos, itemName);
127					} else {
128						// add class current
129						var currentlink = self.el.querySelector('.menu__link--current');
130						if (currentlink) {
131							classie.remove(self.el.querySelector('.menu__link--current'), 'menu__link--current');
132						}
133						classie.add(ev.target, 'menu__link--current');
134
135						// callback
136						self.options.onItemClick(ev, itemName);
137					}
138				});
139			});
140		}
141
142		// back navigation
143		if (this.options.backCtrl) {
144			this.backCtrl.addEventListener('click', function () {
145				self._back();
146			});
147		}
148	};
149
150	MLMenu.prototype._openSubMenu = function (subMenuEl, clickPosition, subMenuName) {
151		if (this.isAnimating) {
152			return false;
153		}
154		this.isAnimating = true;
155
156		// save "parent" menu index for back navigation
157		this.menusArr[this.menus.indexOf(subMenuEl)].backIdx = this.current;
158		// save "parent" menu´s name
159		this.menusArr[this.menus.indexOf(subMenuEl)].name = subMenuName;
160		// current menu slides out
161		this._menuOut(clickPosition);
162		// next menu (submenu) slides in
163		this._menuIn(subMenuEl, clickPosition);
164	};
165
166	MLMenu.prototype._back = function () {
167		if (this.isAnimating) {
168			return false;
169		}
170		this.isAnimating = true;
171
172		// current menu slides out
173		this._menuOut();
174		// next menu (previous menu) slides in
175		var backMenu = this.menusArr[this.menusArr[this.current].backIdx].menuEl;
176		this._menuIn(backMenu);
177
178		// remove last breadcrumb
179		if (this.options.breadcrumbsCtrl) {
180			this.breadcrumbsCtrl.removeChild(this.breadcrumbsCtrl.lastElementChild);
181		}
182	};
183
184	MLMenu.prototype._menuOut = function (clickPosition) {
185		// the current menu
186		var self = this,
187			currentMenu = this.menusArr[this.current].menuEl,
188			isBackNavigation = typeof clickPosition == 'undefined' ? true : false;
189
190		// slide out current menu items - first, set the delays for the items
191		this.menusArr[this.current].menuItems.forEach(function (item, pos) {
192			item.style.WebkitAnimationDelay = item.style.animationDelay = isBackNavigation ? parseInt(pos * self.options.itemsDelayInterval) + 'ms' : parseInt(Math.abs(clickPosition - pos) * self.options.itemsDelayInterval) + 'ms';
193		});
194		// animation class
195		if (this.options.direction === 'r2l') {
196			classie.add(currentMenu, !isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight');
197		} else {
198			classie.add(currentMenu, isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight');
199		}
200	};
201
202	MLMenu.prototype._menuIn = function (nextMenuEl, clickPosition) {
203		var self = this,
204			// the current menu
205			currentMenu = this.menusArr[this.current].menuEl,
206			isBackNavigation = typeof clickPosition == 'undefined' ? true : false,
207			// index of the nextMenuEl
208			nextMenuIdx = this.menus.indexOf(nextMenuEl),
209
210			nextMenuItems = this.menusArr[nextMenuIdx].menuItems,
211			nextMenuItemsTotal = nextMenuItems.length;
212
213		// slide in next menu items - first, set the delays for the items
214		nextMenuItems.forEach(function (item, pos) {
215			item.style.WebkitAnimationDelay = item.style.animationDelay = isBackNavigation ? parseInt(pos * self.options.itemsDelayInterval) + 'ms' : parseInt(Math.abs(clickPosition - pos) * self.options.itemsDelayInterval) + 'ms';
216
217			// we need to reset the classes once the last item animates in
218			// the "last item" is the farthest from the clicked item
219			// let's calculate the index of the farthest item
220			var farthestIdx = clickPosition <= nextMenuItemsTotal / 2 || isBackNavigation ? nextMenuItemsTotal - 1 : 0;
221
222			if (pos === farthestIdx) {
223				onEndAnimation(item, function () {
224					// reset classes
225					if (self.options.direction === 'r2l') {
226						classie.remove(currentMenu, !isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight');
227						classie.remove(nextMenuEl, !isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft');
228					} else {
229						classie.remove(currentMenu, isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight');
230						classie.remove(nextMenuEl, isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft');
231					}
232					classie.remove(currentMenu, 'menu__level--current');
233					classie.add(nextMenuEl, 'menu__level--current');
234
235					//reset current
236					self.current = nextMenuIdx;
237
238					// control back button and breadcrumbs navigation elements
239					if (!isBackNavigation) {
240						// show back button
241						if (self.options.backCtrl) {
242							classie.remove(self.backCtrl, 'menu__back--hidden');
243						}
244
245						// add breadcrumb
246						self._addBreadcrumb(nextMenuIdx);
247					} else if (self.current === 0 && self.options.backCtrl) {
248						// hide back button
249						classie.add(self.backCtrl, 'menu__back--hidden');
250					}
251
252					// we can navigate again..
253					self.isAnimating = false;
254				});
255			}
256		});
257
258		// animation class
259		if (this.options.direction === 'r2l') {
260			classie.add(nextMenuEl, !isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft');
261		} else {
262			classie.add(nextMenuEl, isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft');
263		}
264	};
265
266	MLMenu.prototype._addBreadcrumb = function (idx) {
267		if (!this.options.breadcrumbsCtrl) {
268			return false;
269		}
270
271		var bc = document.createElement('a');
272		bc.innerHTML = idx ? this.menusArr[idx].name : this.options.initialBreadcrumb;
273		this.breadcrumbsCtrl.appendChild(bc);
274
275		var self = this;
276		bc.addEventListener('click', function (ev) {
277			ev.preventDefault();
278
279			// do nothing if this breadcrumb is the last one in the list of breadcrumbs
280			if (!bc.nextSibling || self.isAnimating) {
281				return false;
282			}
283			self.isAnimating = true;
284
285			// current menu slides out
286			self._menuOut();
287			// next menu slides in
288			var nextMenu = self.menusArr[idx].menuEl;
289			self._menuIn(nextMenu);
290
291			// remove breadcrumbs that are ahead
292			var siblingNode;
293			while (siblingNode = bc.nextSibling) {
294				self.breadcrumbsCtrl.removeChild(siblingNode);
295			}
296		});
297	};
298
299	// 초기화 추가
300	MLMenu.prototype.resetMenu = function () {
301		if (this.isAnimating || this.current === 0) {
302			return;
303		}
304		this.isAnimating = true;
305
306		// 현재 메뉴를 숨기기
307		this._menuOut();
308
309		// 첫 번째 메뉴로 이동
310		var firstMenu = this.menusArr[0].menuEl;
311		this._menuIn(firstMenu);
312
313		// 브레드크럼 리셋
314		if (this.options.breadcrumbsCtrl) {
315			while (this.breadcrumbsCtrl.firstChild) {
316				this.breadcrumbsCtrl.removeChild(this.breadcrumbsCtrl.firstChild);
317			}
318			this._addBreadcrumb(0);
319		}
320
321		// 뒤로 가기 버튼 숨기기
322		if (this.options.backCtrl) {
323			classie.add(this.backCtrl, "menu__back--hidden");
324		}
325
326		// 현재 인덱스를 0으로 변경
327		this.current = 0;
328
329		this.isAnimating = false;
330	};
331	//
332
333	window.MLMenu = MLMenu;
334
335})(window);

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.