PageSourceSearch

http://www.ugktid.ru/templates/ja_university/js/menu/mega.js

js ugktid.ru collected 2026-10-07 17:20:57 UTC 18,500 bytes, 749 lines download raw bytes

1/**
2 * ------------------------------------------------------------------------
3 * JA University Template for J25 & J32
4 * ------------------------------------------------------------------------
5 * Copyright (C) 2004-2011 J.O.O.M Solutions Co., Ltd. All Rights Reserved.
6 * @license - Copyrighted Commercial Software
7 * Author: J.O.O.M Solutions Co., Ltd
8 * Websites:  http://www.joomlart.com -  http://www.joomlancers.com
9 * This file may not be redistributed in whole or significant part.
10 * ------------------------------------------------------------------------
11 */
12var JRMenu = window.JRMenu || {};
13var jaMegaMenuMoo = new Class({
14
15	Implements: Options,
16
17	options: {
18		slide: 0, 				//enable slide
19		duration: 300, 			//slide speed. lower for slower, bigger for faster
20		fading: 0,				//Enable fading
21		bgopacity: 0.9, 		//set the transparent background. 0 to disable, 0<bgopacity<1: the opacity of the background
22		delayHide: 500,
23		direction: 'down',
24		action: 'mouseenter', 	//mouseenter or click
25		hidestyle: 'normal',
26		offset: -5,
27		fixArrow: false
28	},
29
30	toElement: function () {
31		return this.menu;
32	},
33
34	initialize: function (menu, options) {
35		this.menu = $(menu);
36		if (!this.menu) {
37			return;
38		}
39		this.setOptions(options);
40
41		//ignore delayHide if no animation
42		if (!this.options.slide && !this.options.fading) {
43			this.options.delayHide = 10;
44		}
45		
46		JRMenu.inst = this;
47		this.menu.addClass('mm-enable');
48		this.childopen = [];
49		this.imgloaded = false;
50		this.loaded = false;
51		this.addnavbtn();
52		this.prepare();
53	},
54
55	addnavbtn: function(){
56		
57		if (!(Browser.ie && Browser.version < 9)) {
58			var jlevel0 = this.menu.getElement('ul.level0');
59			if(jlevel0){
60				var jmega = this.menu,
61					jbutton = new Element ('div', {id:'ja-menu-button', html: 'Navigation', styles: { display: 'none'}}).inject (jmega, 'before');
62				
63				jbutton.addEvent('click', function(e){
64					e.stop();
65
66					if(jmega.getStyle('display') == 'block'){
67						jmega.removeClass('active').setStyle('display', 'none');
68						jbutton.removeClass('active');
69					} else {
70						jmega.addClass('active').setStyle('display', 'block');
71						jbutton.addClass('active');
72					}
73				});
74				
75				$(document).addEvent('click', function(){
76					if(!jmega.hasClass('mm-enable')){
77						jmega.removeClass('active').setStyle('display', 'none');
78					}
79					
80					jbutton.removeClass('active');
81				});
82			}
83
84			JRMenu.mmenuid = null;
85    		window.addEvent('resize', function(){
86    			clearTimeout(JRMenu.mmenuid);
87    			JRMenu.mmenuid = setTimeout(function(){JRMenu.inst.start();}, 100);
88    		});
89		}
90	},
91
92	prepare: function () {
93		//preload images
94		var imgElms = this.menu.getElements('img');
95		if (imgElms.length && !this.imgloaded) {
96			var imgSrcs = [];
97			imgElms.each(function (image) {
98				imgSrcs.push(image.src)
99			});
100
101			new Asset.images(imgSrcs, {
102				onComplete: function () {
103					this.imgloaded = true;
104					this.start();
105				}.bind(this)
106			});
107			
108			//call this start if cannot load image after sometime
109			setTimeout(function(){ 
110				this.imgloaded = true;
111				this.start();
112			}.bind(this), 3000);
113		} else {
114			window.addEvent('load', function(){
115			   this.imgloaded = true;
116			   this.start();
117            }.bind(this));
118		}   
119	},
120
121	detect: function(){
122		var jbutton = $('ja-menu-button'),
123			rs = true;
124
125		if(jbutton){	
126			rs = jbutton.getComputedStyle('display') == 'none';
127			if(rs != this.menu.hasClass('mm-enable')){
128				this.menu[rs ? 'addClass' : 'removeClass']('mm-enable');
129				this.menu.setStyle('display', rs ? 'block' : 'none');
130			}
131		}
132		
133		return rs;
134	},
135	start: function () {
136		//init once
137		if (!this.detect() || !this.imgloaded || this.loaded) {
138			return;
139		}
140		
141		this.loaded = true;
142		this.zindex = 1000;
143		
144		//get wrapper
145		var pw = this.menu;
146		while (pw = pw.getParent()) {
147			if (pw.hasClass('main') || pw.hasClass('wrap')) {
148				this.wrapper = pw;
149				break;
150			}
151		}
152
153		this.items = this.menu.getElements('li.mega');
154		this.items.each(function (li) {
155			//link item
156			var link = li.getChildren('a.mega')[0],
157				child = li.getChildren('.childcontent')[0],
158				level0 = li.getParent().hasClass('level0'),
159				parent = this.getParent(li),
160				item = {
161					stimer: null,
162					direction: ((level0 && this.options.direction == 'up') ? 0 : 1)
163				};
164
165			//child content
166			if (child) {
167				var childwrap = child.getElement('.childcontent-inner-wrap'),
168					childinner = child.getElement('.childcontent-inner'),
169					width = childinner.getWidth(),
170					height = childinner.getHeight(),
171					padding = childwrap.getStyle('padding-left').toInt() + childwrap.getStyle('padding-right').toInt(),
172					overflow = false;
173
174				child.setStyles({
175					width: width + 20,
176					height: height + 20
177				});
178
179				childwrap.setStyle('width', width);
180
181				if (['auto', 'scroll'].contains(childinner.getStyle('overflow'))) {
182					overflow = true;
183
184					//fix for ie6/7
185					if (Browser.ie) {
186						if (Browser.version <= 7) {
187							childinner.setStyle('position', 'relative');
188						}
189
190						if (Browser.version == 6) {
191							childinner.setStyle('height', childinner.getStyle('max-height') || 400);
192						}
193					}
194				}
195
196				//show direction
197				if (this.options.direction == 'up') {
198					if (level0) {
199						child.setStyle('top', -child.getHeight()); //ajust top position
200					} else {
201						child.setStyle('bottom', 0);
202					}
203				}
204			}
205
206			if (child && this.options.bgopacity) {
207				//Make transparent background
208				new Element('div', {
209					'class': 'childcontent-bg',
210					styles: {
211						width: '100%',
212						height: height,
213						opacity: this.options.bgopacity,
214						position: 'absolute',
215						top: 0,
216						left: 0,
217						zIndex: 1,
218						background: child.getStyle('background'),
219						backgroundImage: child.getStyle('background-image'),
220						backgroundRepeat: child.getStyle('background-repeat'),
221						backgroundColor: child.getStyle('background-color')
222					}
223				}).inject(childwrap, 'top');
224
225				child.setStyle('background', 'none');
226				childwrap.setStyles({
227					position: 'relative',
228					zIndex: 2
229				});
230			}
231
232			if (child && (this.options.slide || this.options.fading)) {
233
234				if (child.hasClass('right')) {
235					child.setStyle('right', 0);
236				}
237
238				//init Fx.Styles for childcontent
239				var fx = new Fx.Morph(childwrap, {
240					duration: this.options.duration,
241					transition: Fx.Transitions.linear,
242					onComplete: this.itemAnimDone.bind(this, item),
243					link: 'cancel'
244				}),
245					stylesOn = {};
246
247				if (this.options.slide) {
248					if (level0) {
249						stylesOn[item.direction == 1 ? 'margin-top' : 'bottom'] = 0;
250					} else {
251						stylesOn[window.isRTL ? 'margin-right' : 'margin-left'] = 0;
252					}
253				}
254				if (this.options.fading) {
255					stylesOn['opacity'] = 1;
256				}
257			}
258
259			if (child && this.options.action == 'click') {
260				li.addEvent('click', function (e) {
261					e.stopPropagation();
262
263					if (li.hasClass('group')) {
264						return;
265					}
266
267					if (item.status == 'open') {
268						if (this.cursorIn(li, e)) {
269							this.itemHide(item);
270						} else {
271							this.hideOthers(li);
272						}
273					} else {
274						this.itemShow(item);
275					}
276				}.bind(this));
277			}
278
279			if (this.options.action == 'mouseover' || this.options.action == 'mouseenter') {
280				li.addEvent('mouseover', function (e) {
281					if (li.hasClass('group')) {
282						return;
283					}
284
285					e.stop();
286					
287					clearTimeout(item.stimer);
288					clearTimeout(this.atimer);
289
290					this.intent(item, 'open');
291					this.itemShow(item);
292
293				}.bind(this))
294
295				.addEvent('mouseleave', function (e) {
296					if (li.hasClass('group')) {
297						return;
298					}
299
300					clearTimeout(item.stimer);
301
302					this.intent(item, 'close');
303					if (child) {
304						item.stimer = this.itemHide.delay(this.options.delayHide, this, [item]);
305					} else {
306						this.itemHide(item);
307					}
308				}.bind(this));
309
310				//if has childcontent, don't goto link before open childcontent - fix for touch screen
311				if (link && child) {
312					link.addEvent('click', function (e) {
313						if (!item.clickable) {
314							e.stop();
315						}
316					});
317				}
318
319				//stop if click on menu item - prevent raise event to container => hide all open submenu
320				li.addEvent('click', function (e) {
321					e.stopPropagation()
322				});
323
324				if (child) {
325					child.addEvent('mouseover', function () {
326						clearTimeout(item.stimer);
327						clearTimeout(this.atimer);
328
329						this.intent(item, 'open');
330						this.itemShow(item);
331					}.bind(this)).addEvent('mouseleave', function (e) {
332						e.stop();
333
334						this.intent(item, 'close');
335						clearTimeout(item.stimer);
336
337						if (!this.cursorIn(item.el, e)) {
338							this.atimer = this.hideAlls.delay(this.options.delayHide, this);
339						}
340					}.bind(this))
341				}
342			}
343
344			//when click on a link - close all open childcontent
345			if (link && !child) {
346				link.addEvent('click', function (e) {
347					e.stopPropagation(); //prevent to raise event up
348					this.hideOthers(null);
349					//Remove current class
350					this.menu.getElements('.active').removeClass('active');
351
352					//Add current class
353					var p = li;
354					while (p) {
355						var idata = p.retrieve('item');
356
357						p.addClass('active');
358						idata.link.addClass('active');
359						p = idata.parent;
360					}
361				}.bind(this));
362			}
363
364			Object.append(item, {
365				el: li,
366				parent: parent,
367				link: link,
368				child: child,
369				childwrap: childwrap,
370				childinner: childinner,
371				width: width,
372				height: height,
373				padding: padding,
374				level0: level0,
375				fx: fx,
376				stylesOn: stylesOn,
377				overflow: overflow,
378				clickable: !(link && child)
379			});
380
381			li.store('item', item);
382		}, this);
383
384		//click on windows will close all submenus
385		var container = $('ja-wrapper');
386		if (!container) {
387			container = document.body;
388		}
389
390		container.addEvent('click', function (e) {
391			this.hideAlls();
392		}.bind(this));
393
394		this.menu.getElements('.childcontent').setStyle('display', 'none');
395	},
396
397	getParent: function (el) {
398		var p = el;
399		while ((p = p.getParent())) {
400			if (this.items.contains(p) && !p.hasClass('group')) {
401				return p;
402			}
403
404			if (!p || p == this.menu) {
405				return null;
406			}
407		}
408	},
409
410	intent: function (item, action) {
411		item.intent = action;
412
413		while (item.parent && (item = item.parent.retrieve('item'))) {
414			item.intent = action;
415		}
416	},
417
418	cursorIn: function (el, event) {
419		if (!el || !event) {
420			return false;
421		}
422
423		var pos = el.getPosition(),
424			cursor = event.page;
425
426		return (cursor.x > pos.x && cursor.x < pos.x + el.getWidth() && cursor.y > pos.y && cursor.y < pos.y + el.getHeight());
427	},
428
429	itemOver: function (item) {
430		item.el.addClass('over');
431
432		if (item.el.hasClass('haschild')) {
433			item.el.removeClass('haschild').addClass('haschild-over');
434		}
435
436		if (item.link) {
437			item.link.addClass('over');
438		}
439	},
440
441	itemOut: function (item) {
442		item.el.removeClass('over');
443
444		if (item.el.hasClass('haschild-over')) {
445			item.el.removeClass('haschild-over').addClass('haschild');
446		}
447
448		if (item.link) {
449			item.link.removeClass('over');
450		}
451	},
452
453	itemShow: function (item) {
454		if(!this.menu.hasClass('mm-enable')){
455			return;
456		}
457		
458			if(this.childopen.indexOf(item) < this.childopen.length -1){
459				this.hideOthers(item.el);
460			}
461		if (item.status == 'open') {
462			return; //don't need do anything
463		}
464
465		//Setup the class
466		this.itemOver(item);
467
468		//push to show queue
469		if (item.level0) {
470			this.childopen.length = 0;
471		}
472
473		if (item.child) {
474			this.childopen.push(item);
475		}
476
477		item.intent = 'open';
478		item.status = 'open';
479
480		this.enableclick.delay(100, this, item);
481
482		if (item.child) {
483			//reposition the submenu
484			this.positionSubmenu(item);
485
486			if (item.fx && !item.stylesOff) {
487				item.stylesOff = {};
488				if (this.options.slide) {
489					if (item.level0) {
490						item.stylesOff[item.direction == 1 ? 'margin-top' : 'bottom'] = -item.height;
491					} else {
492						item.stylesOff[window.isRTL ? 'margin-right' : 'margin-left'] = (item.direction == 1 ? -item.width : item.width);
493					}
494				}
495				if (this.options.fading) {
496					item.stylesOff['opacity'] = 0;
497				}
498				item.fx.set(item.stylesOff);
499			}
500
501			item.child.setStyles({
502				display: 'block',
503				zIndex: this.zindex++
504			});
505		}
506
507		if (!item.fx || !item.child) {
508			return;
509		}
510
511		item.child.setStyle('overflow', 'hidden');
512		if (item.overflow) {
513			item.childinner.setStyle('overflow', 'hidden');
514		}
515
516		item.fx.start(item.stylesOn);
517	},
518
519	itemHide: function (item) {
520		if(!this.menu.hasClass('mm-enable')){
521			return;
522		}
523		
524		clearTimeout(item.stimer);
525
526		item.status = 'close';
527		item.intent = 'close';
528
529		this.itemOut(item);
530		this.childopen.erase(item);
531
532		if (!item.fx && item.child) {
533			item.child.setStyle('display', 'none');
534		}
535
536		if (!item.fx || !item.child || item.child.getStyle('opacity') == '0') {
537			return;
538		}
539
540		item.child.setStyle('overflow', 'hidden');
541		if (item.overflow) {
542			item.childinner.setStyle('overflow', 'hidden');
543		}
544
545		switch (this.options.hidestyle) {
546		case 'fast':
547			item.fx.options.duration = 100;
548			item.fx.start(item.stylesOff);
549			break;
550		case 'fastwhenshow':
551			item.fx.start(Object.merge(item.stylesOff, {
552				'opacity': 0
553			}));
554			break;
555		case 'normal':
556		default:
557			item.fx.start(item.stylesOff);
558			break;
559		}
560	},
561
562	itemAnimDone: function (item) {
563		//hide done
564		if (item.status == 'close') {
565			//reset duration and enable opacity if not fading
566			if (this.options.hidestyle.test(/fast/)) {
567				item.fx.options.duration = this.options.duration;
568				if (!this.options.fading) {
569					item.childwrap.setStyle('opacity', 1);
570				}
571			}
572			//hide
573			item.child.setStyle('display', 'none');
574			this.disableclick.delay(100, this, item);
575
576			var pitem = item.parent ? item.parent.retrieve('item') : null;
577			if (pitem && pitem.intent == 'close') {
578				this.itemHide(pitem);
579			}
580		}
581
582		//show done
583		if (item.status == 'open') {
584			item.child.setStyle('overflow', '');
585			if (item.overflow) {
586				item.childinner.setStyle('overflow-y', 'auto');
587			}
588
589			item.childwrap.setStyle('opacity', 1);
590			item.child.setStyle('display', 'block');
591		}
592	},
593
594	hideOthers: function (el) {
595		this.childopen.each(function (item) {
596			if (!el || (item.el != el && !item.el.contains(el))) {
597				item.intent = 'close';
598			}
599		});
600
601		var last = this.childopen.getLast();
602		if (last && last.intent == 'close') {
603			this.itemHide(last);
604		}
605	},
606
607	hideAlls: function (el) {
608		this.childopen.flatten().each(function (item) {
609			if (!item.fx) {
610				this.itemHide(item);
611			} else {
612				item.intent = 'close';
613			}
614		}, this);
615
616		if (this.options.slide || this.options.fading) {
617			var last = this.childopen.getLast();
618			if (last && last.intent == 'close') {
619				this.itemHide(last);
620			}
621		}
622	},
623
624	enableclick: function (item) {
625		if (item.link && item.child) {
626			item.clickable = true;
627		}
628	},
629
630	disableclick: function (item) {
631		item.clickable = false;
632	},
633
634	positionSubmenu: function (item) {
635		var options = this.options, offsleft, offstop, left, top, stylesOff = {},
636			icoord = item.el.getCoordinates(),
637			bodySize = $(document.body).getScrollSize(),
638			winRect = {
639				top: window.getScrollTop(),
640				left: window.getScrollLeft(),
641				width: window.getWidth(),
642				height: window.getHeight()
643			},
644			wrapRect = this.wrapper ? this.wrapper.getCoordinates() : {
645				top: 0,
646				left: 0,
647				width: winRect.width,
648				height: winRect.height
649			};
650
651		winRect.top = Math.max(winRect.top, wrapRect.top);
652		winRect.left = Math.max(winRect.left, wrapRect.left);
653		winRect.width = Math.min(winRect.width, wrapRect.width);
654		winRect.height = Math.min(winRect.height, $(document.body).getScrollHeight());
655		winRect.right = winRect.left + winRect.width;
656		winRect.bottom = winRect.top + winRect.height;
657
658		if (!item.level0) {
659			var pitem = item.parent.retrieve('item'),
660				offsety = parseFloat(pitem.child.getFirst().getStyle('margin-top')),
661				offsetx = parseFloat(pitem.child.getFirst().getStyle(window.isRTL ? 'margin-right' : 'margin-left'));
662
663			item.direction = pitem.direction;
664
665			window.isRTL && (offsetx = 0 - offsetx);
666			icoord.top -= offsety;
667			icoord.bottom -= offsety;
668			icoord.left -= offsetx;
669			icoord.right -= offsetx;
670		}
671
672		if (item.level0) {
673			if (window.isRTL) {
674				offsleft = Math.max(winRect.left, icoord.right - item.width - 20);
675				left = Math.max(0, offsleft - winRect.left);
676			} else {
677				offsleft = Math.max(winRect.left, Math.min(winRect.right - item.width, icoord.left));
678				left = Math.max(0, Math.min(winRect.right - item.width, icoord.left) - winRect.left);
679			}
680		} else {
681			if (window.isRTL) {
682				if (item.direction == 1) {
683					offsleft = icoord.left - item.width - 20 + options.offset;
684					left = -icoord.width - 20;
685
686					if (offsleft < winRect.left) {
687						item.direction = 0;
688						offsleft = Math.min(winRect.right, Math.max(winRect.left, icoord.right + item.padding - 20 - options.offset));
689						left = icoord.width - 20;
690						stylesOff['margin-right'] = item.width;
691					}
692				} else {
693					offsleft = icoord.right + item.padding - 20;
694					left = icoord.width - 20;
695
696					if (offsleft + item.width > winRect.right) {
697						item.direction = 1;
698						offsleft = Math.max(winRect.left, icoord.left - item.width - 20);
699						left = -icoord.width - 20;
700						stylesOff['margin-right'] = -item.width;
701					}
702				}
703			} else {
704
705				if (item.direction == 1) {
706					offsleft = icoord.right - options.offset;
707					left = icoord.width;
708
709					if (offsleft + item.width > winRect.right) {
710						item.direction = 0;
711						offsleft = Math.max(winRect.left, icoord.left - item.width - item.padding + options.offset);
712						left = -icoord.width;
713						stylesOff['margin-left'] = item.width;
714					}
715				} else {
716					offsleft = icoord.left - item.width - item.padding + options.offset;
717					left = -icoord.width;
718
719					if (offsleft < winRect.left) {
720						item.direction = 1;
721						offsleft = Math.max(winRect.left, Math.min(winRect.right - item.width, icoord.right - options.offset));
722						left = icoord.width;
723						stylesOff['margin-left'] = -item.width;
724					}
725				}
726			}
727		}
728
729		if (options.slide && item.fx && Object.getLength(stylesOff)) {
730			item.fx.set(stylesOff);
731		}
732
733		// Teline IV
734		if (options.fixArrow && item.childinner) {
735			item.childinner.setStyle('background-position', (icoord.left - offsleft + (icoord.width / 2 - 4.5)) + 'px top');
736		}
737
738		var oldp = item.child.getStyle('display');
739		item.child.setStyle('display', 'block');
740		if (item.child.getOffsetParent()) {
741			left = offsleft - item.child.getOffsetParent().getCoordinates().left;
742		}
743		item.child.setStyles({
744			'margin-left': 0,
745			'left': left,
746			'display': oldp
747		});
748	}
749});

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.