PageSourceSearch

http://www.senica.ru/templates/ja_teline_iv/js/menu/mega.js

js senica.ru collected 2026-10-02 15:13:21 UTC 18,554 bytes, 548 lines download raw bytes

1/**
2 * ------------------------------------------------------------------------
3 * JA T3 System plugin for Joomla 1.7
4 * ------------------------------------------------------------------------
5 * Copyright (C) 2004-2011 J.O.O.M Solutions Co., Ltd. All Rights Reserved.
6 * @license - GNU/GPL, http://www.gnu.org/licenses/gpl.html
7 * Author: J.O.O.M Solutions Co., Ltd
8 * Websites: http://www.joomlart.com - http://www.joomlancers.com
9 * ------------------------------------------------------------------------
10 */
11
12var jaMegaMenuMoo = new Class({
13
14	initialize: function(menu, options){
15		this.options = $extend({
16			slide:	true, //enable slide
17			duration: 300, //slide speed. lower for slower, bigger for faster
18			fading: false, //Enable fading
19			bgopacity: 0.9, //set the transparent background. 0 to disable, 0<bgopacity<1: the opacity of the background
20			delayHide: 500,
21			direction: 'down',
22			action: 'mouseenter', //mouseenter or click
23			hidestyle: 'normal'
24		}, options || {});
25		//ignore delayHide if no animation
26		if (!this.options.slide && !this.options.fading) this.options.delayHide = 10;
27		
28		this.menu = menu;
29		this.childopen = new Array();
30		this.imageloaded = false;
31		this.loaded = false;
32		//window.addEvent('load', this.start.bind(this));
33		this.start();
34	},
35	
36	start: function () {
37		//do nothing if loaded
38		if (this.loaded) return;
39		
40		this.menu = $(this.menu);
41		//preload images
42		var images = this.menu.getElements ('img');
43		if (images && images.length && !this.imageloaded) {
44			var imgs = [];
45			images.each (function (image) {imgs.push(image.src)});
46			if (imgs.length) {
47				new Asset.images(imgs, {			
48					onComplete: function(){
49						this.start();
50					}.bind(this)
51				});
52				this.imageloaded = true;
53				
54				//call this start if cannot load image after sometime
55				this.start.delay (3000, this);
56				return ;
57			}
58		}
59		
60		//mark as called
61		this.loaded = true;
62		
63		//get wrapper
64		p = this.menu;
65		while (p=p.getParent()) {
66			if (p.hasClass ('main') || p.hasClass ('wrap')) {this.wrapper = p; break;}
67		}
68		this.items = this.menu.getElements ('li.mega');
69		//this.items.setStyle ('position', 'relative');
70		this.items.each (function(li) {
71			//link item
72			if ((a = li.getElement('a.mega')) && this.isChild (a, li)) li.a = a;
73			else li.a = null;
74			//parent
75			li._parent = this.getParent (li);
76			//child content
77			if ((childcontent = li.getElement('.childcontent')) && this.isChild (childcontent, li)) {
78				li.childcontent = childcontent;
79				li.childcontent_inner = li.childcontent.getElement ('.childcontent-inner-wrap');
80				var coor = li.childcontent_inner.getCoordinates ();
81				li._w = li.getElement('.childcontent-inner').offsetWidth;
82				li._h = li.getElement('.childcontent-inner').offsetHeight;
83
84				li.level0 = li.getParent().hasClass('level0');
85				//
86				li.childcontent.setStyles ({'width':li._w+10, 'height':li._h});
87				li.childcontent_inner.setStyles ({'width':li._w});
88				//fix for overflow
89				li.childcontent_inner1 = li.childcontent.getElement ('.childcontent-inner');
90				li.childcontent_inner1.ol = false;
91				if (li.childcontent_inner1.getStyle ('overflow') == 'auto' || li.childcontent_inner1.getStyle ('overflow') == 'scroll') {
92					li.childcontent_inner1.ol = true;
93					//fix for ie6/7
94					if (window.ie6 || window.ie7) {
95						li.childcontent_inner1.setStyle ('position', 'relative');
96					}
97					
98					if (window.ie6) {
99						li.childcontent_inner1.setStyle ('height', li.childcontent_inner1.getStyle ('max-height') || 400);
100					}
101				}
102
103				//show direction
104				if (this.options.direction == 'up') {
105					if (li.level0) {
106						li.childcontent.setStyle ('top', -li.childcontent.offsetHeight); //ajust top position
107					} else {
108						li.childcontent.setStyle ('bottom', 0);
109					}
110				}
111			}
112			else li.childcontent = null;
113			
114			if (li.childcontent && this.options.bgopacity) {
115				//Make transparent background
116				var bg = new Element ('div', {'class':'childcontent-bg'});
117				bg.injectTop (li.childcontent_inner);
118				bg.setStyles ({'width':'100%', 'height':li._h, 'opacity':this.options.bgopacity,
119								'position': 'absolute', 'top': 0, 'left': 0, 'z-index': 1
120								});
121				if (li.childcontent.getStyle('background')) bg.setStyle ('background', li.childcontent.getStyle('background'));
122				if (li.childcontent.getStyle('background-image')) bg.setStyle ('background-image', li.childcontent.getStyle('background-image'));
123				if (li.childcontent.getStyle('background-repeat')) bg.setStyle ('background-repeat', li.childcontent.getStyle('background-repeat'));
124				if (li.childcontent.getStyle('background-color')) bg.setStyle ('background-color', li.childcontent.getStyle('background-color'));
125				li.childcontent.setStyle ('background', 'none');
126				li.childcontent_inner.setStyles ({'position':'relative', 'z-index': 2});
127			}
128			
129			if (li.childcontent && (this.options.slide || this.options.fading)) {
130				//li.childcontent.setStyles ({'width': li._w});
131				li.childcontent.setStyles ({'left':'auto'});
132				if (li.childcontent.hasClass ('right')) li.childcontent.setStyle ('right', 0);
133				if (this.options.slide) {
134					li.childcontent.setStyles ({'left':'auto', 'overflow':'hidden'});
135					if (li.level0) {
136						if (this.options.direction == 'up') {
137							li.childcontent_inner.setStyle ('bottom', -li._h-20);
138						} else {
139							li.childcontent_inner.setStyle ('margin-top', -li._h-20);
140						}
141						
142					} else {					
143						li.childcontent_inner.setStyle ('margin-left', -li._w-20);
144					}
145				}
146				if (this.options.fading) {
147					li.childcontent_inner.setStyle ('opacity', 0);
148				}
149				//Init Fx.Styles for childcontent
150				//li.fx = new Fx.Styles(li.childcontent_inner, {duration: this.options.duration, transition: Fx.Transitions.linear, onComplete: this.itemAnimDone.bind(this, li)});
151				//li.fx = new Fx.Tween (li.childcontent_inner, {duration: this.options.duration, transition: Fx.Transitions.linear, onComplete: this.itemAnimDone.bind(this, li)});
152				// Dohq: Fix for use both fade & slide
153				li.fx = new Fx.Morph (li.childcontent_inner, {duration: this.options.duration, transition: Fx.Transitions.linear, onComplete: this.itemAnimDone.bind(this, li)});
154				//effect
155				//li.eff_on = {p:[],to:[]};
156				//li.eff_off = {p:[],to:[]};
157				li.eff_on  = {};
158				li.eff_off = {};
159				if (this.options.slide) {
160					if (li.level0) {
161						if (this.options.direction == 'up') {
162							li.eff_on ['bottom'] = 0;
163							li.eff_off ['bottom'] = -li._h;
164							
165//							li.eff_on.p.push ('bottom');
166//							li.eff_on.to.push (0);
167//							li.eff_off.p.push ('bottom');
168//							li.eff_off.to.push (-li._h);
169						} else {
170							li.eff_on ['margin-top'] = 0;
171							li.eff_off ['margin-top'] = -li._h;
172							
173//							li.eff_on.p.push ('margin-top');
174//							li.eff_on.to.push (0);
175//							li.eff_off.p.push ('margin-top');
176//							li.eff_off.to.push (-li._h);
177						}
178					} else {
179						li.eff_on['margin-left'] = 0;
180						li.eff_off['margin-left'] = -li._w;
181						
182//						li.eff_on.p.push ('margin-left');
183//						li.eff_on.to.push (0);
184//						li.eff_off.p.push ('margin-left');
185//						li.eff_off.to.push (-li._w);
186					}
187				}
188				if (this.options.fading) {
189					li.eff_on ['opacity'] = 1;
190					li.eff_off['opacity'] = 0;
191//					li.eff_on = ['opacity',1];
192//					li.eff_off = ['opacity',0];
193					
194//					li.eff_on.p.push ('opacity');
195//					li.eff_on.to.push (1);
196//					li.eff_off.p.push ('opacity');
197//					li.eff_off.to.push (0);
198				}
199			}
200			
201			if (this.options.action=='click' && li.childcontent) {
202				li.addEvent('click', function(e) {
203					var event = new Event (e);
204					if (li.hasClass ('group')) return;
205					if (li.childcontent) {
206						if (li.status == 'open') {
207							if (this.cursorIn (li, event)) {
208								this.itemHide (li);
209							} else {
210								this.itemHideOthers(li);
211							}
212						} else {
213							this.itemShow (li);
214						}
215					} else {
216						if (li.a) location.href = li.a.href;
217					}
218					event.stopPropagation();
219				}.bind (this));			
220			}
221
222			if (this.options.action == 'mouseover' || this.options.action == 'mouseenter') {
223				li.addEvent('mouseenter', function(e) {
224					if (li.hasClass ('group')) return;
225					$clear (li.timer);
226					this.itemShow (li);
227					if (!e.stopped) {
228						e.stopPropagation();
229						e.stopped = true; //make sure the stop function is call only once
230					}
231				}.bind (this));
232				
233				li.addEvent('mouseleave', function(e) {
234					if (li.hasClass ('group')) return;
235					$clear (li.timer);
236					if (li.childcontent) li.timer = this.itemHide.delay(this.options.delayHide, this, [li, e]);
237					else this.itemHide (li, e);
238					if (!e.stopped) {
239						e.stopPropagation();
240						e.stopped = true; //make sure the stop function is call only once
241					}
242				}.bind (this));
243				
244				//if has childcontent, don't goto link before open childcontent - f
244ix for touch screen
245				if (li.a && li.childcontent) {
246					li.clickable = false;
247					li.a.addEvent ('click',function (e){
248						if (!li.clickable) {
249							new Event(e).stop();
250						}
251					}.bind (this));
252				}
253				
254				//stop if click on menu item - prevent raise event to container => hide all open submenu
255				li.addEvent ('click', function (e) {new Event(e).stopPropagation()});
256			}
257			
258			//when click on a link - close all open childcontent
259			if (li.a && !li.childcontent) {
260				li.a.addEvent ('click',function (e){
261					this.itemHideOthers (null);
262					//Remove current class
263					this.menu.getElements ('.active').removeClass ('active');
264					//Add current class
265					var p = li;
266					while (p) {
267						p.addClass ('active');
268						p.a.addClass ('active');
269						p = p._parent;
270					}
271					new Event (e).stopPropagation();//prevent to raise event up
272				}.bind (this));
273			}
274			
275			if (li.childcontent) this.positionSubmenu (li);
276		},this);
277		
278		//click on windows will close all submenus
279		var container = $('ja-wrapper');
280		if (!container) container = document.body;
281		container.addEvent ('click',function (e) {
282			this.itemHideOthers(null);
283		}.bind(this));				
284		
285		if (this.options.slide || this.options.fading) {
286			//hide all content child
287			this.menu.getElements('.childcontent').setStyle ('display', 'none');
288		}
289		
290	}, 
291	
292	getParent: function (li) { 
293		var p = li;
294		while ((p=p.getParent())) {
295			if (this.items.contains (p) && !p.hasClass ('group')) return p;
296			if (!p || p == this.menu) return null;
297		}
298	},
299	
300	cursorIn: function (el, event) {
301		if (!el || !event) return false;
302		var pos = $merge (el.getPosition(), {'w':el.offsetWidth, 'h': el.offsetHeight});;
303		var cursor = {'x': event.page.x, 'y': event.page.y};
304	
305		if (cursor.x>pos.x && cursor.x<pos.x+el.offsetWidth
306				&& cursor.y>pos.y && cursor.y<pos.y+el.offsetHeight) return true;			
307		return false;
308	},
309	
310	isChild: function (child, parent) {
311		return !!parent.getChildren().contains (child);
312	},
313	
314	itemOver: function (li) {
315		if (li.hasClass ('haschild')) 
316			li.removeClass ('haschild').addClass ('haschild-over');
317		li.addClass ('over');
318		if (li.a) {
319			li.a.addClass ('over');
320		}
321	},
322	
323	itemOut: function (li) {
324		if (li.hasClass ('haschild-over'))
325			li.removeClass ('haschild-over').addClass ('haschild');
326		li.removeClass ('over');
327		if (li.a) {
328			li.a.removeClass ('over');
329		}
330	},
331
332	itemShow: function (li) {
333		clearTimeout(li.timer);
334		if (li.status == 'open') return; //don't need do anything
335		//Setup the class
336		this.itemOver (li);
337		//push to show queue
338		li.status = 'open';
339		this.enableclick.delay (100, this, li);
340		this.childopen.push (li);
341		//hide other
342		this.itemHideOthers (li);
343		if (li.childcontent) {
344			//reposition the submenu
345			this.positionSubmenu (li);
346		}
347		
348
349		if (!$defined(li.fx) || !$defined(li.childcontent)) return;
350		
351		li.childcontent.setStyle ('display', 'block');
352		
353		li.childcontent.setStyles ({'overflow': 'hidden'});		
354		if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow': 'hidden'});
355		li.fx.cancel();
356		
357		li.fx.start (li.eff_on);
358		//li.fx.start (li.eff_on.p, li.eff_on.to);
359		//if (li._parent) this.itemShow (li._parent);
360	},
361	
362	itemHide: function (li, e) {
363		if (e && e.page) { //if event
364			if (this.cursorIn (li, e) || this.cursorIn (li.childcontent, e)) {
365				return;
366			} //cursor in li
367			var p=li._parent;
368			if (p && !this.cursorIn (p, e) && !this.cursorIn(p.childcontent, e)) {
369				p.fireEvent ('mouseleave', e); //fire mouseleave event
370			}
371		}
372		clearTimeout(li.timer);
373		this.itemOut(li);
374		li.status = 'close';
375		this.childopen.erase (li);
376		
377		if (!$defined(li.fx) || !$defined(li.childcontent)) return;
378		
379		if (li.childcontent.getStyle ('opacity') == 0) return;
380		li.childcontent.setStyles ({'overflow': 'hidden'});
381		if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow': 'hidden'});
382		li.fx.cancel();
383		switch (this.options.hidestyle) {
384		case 'fast': 
385			li.fx.options.duration = 100;
386			li.fx.start(Object.merge(li.eff_off,{'opacity':0}));
387			//li.fx.start ($merge(li.eff_off,{'opacity':0}));
388			//li.fx.start(li.eff_off.p, li.eff_off.to);
389			break;
390		case 'fastwhenshow': //when other show
391			if (!e) { //force hide, not because of event => hide fast
392				li.fx.start (Object.merge(li.eff_off,{'opacity':0}));
393				//li.fx.options.duration = 300;
394				//li.fx.start ($merge(li.eff_off,{'opacity':0}));
395				//li.fx.start(li.eff_off.p, li.eff_off.to);
396			} else {	//hide as normal
397				li.fx.start (li.eff_off);
398				//li.fx.start (li.eff_off);
399				//li.fx.start(li.eff_off.p, li.eff_off.to);
400			}
401			break;
402		case 'normal':
403		default:
404			li.fx.start (li.eff_off);
405			//li.fx.start(li.eff_off.p, li.eff_off.to);
406			break;
407		}
408		//li.fx.start (li.eff_off);		
409	},
410	
411	itemAnimDone: function (li) {
412		//hide done
413		if (li.status == 'close'){
414			//reset duration and enable opacity if not fading
415			if (this.options.hidestyle.test (/fast/)) {
416				li.fx.options.duration = this.options.duration;
417				if (!this.options.fading) li.childcontent_inner.setStyle ('opacity', 1);
418			}
419			//hide
420			li.childcontent.setStyles ({'display': 'none'});
421			this.disableclick.delay (100, this, li);
422		}
423		
424		//show done
425		if (li.status == 'open'){
426			li.childcontent.setStyles ({'overflow': ''});
427			if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow-y': 'auto'});
428			li.childcontent_inner.setStyle ('opacity', 1);
429			li.childcontent.setStyles ({'display': 'block'});
430		}
431	},
432	
433	itemHideOthers: function (el) {
434		var fakeevent = null
435		if (el && !el.childcontent) fakeevent = {};
436		var curopen = this.childopen;
437		curopen.each (function(li) {
438			if (li && typeof (li.status) != 'undefined' && (!el || (li != el && !li.hasChild (el)))) {
439				this.itemHide(li, fakeevent);
440			}
441		},this);
442	},
443
444	enableclick: function (li) {
445		if (li.a && li.childcontent) li.clickable = true;
446	},
447	disableclick: function (li) {
448		if (li.a && li.childcontent) li.clickable = false;
449	},
450	
451	positionSubmenu: function (li) {
452		if (li.level0) {
453			if (!window.isRTL) {
454				//check position
455				var lcor = li.getCoordinates();
456				var ccor = li.childcontent.getCoordinates();
457				if(!ccor.width)
458				{
459					li.childcontent.setStyle ('display', 'block');
460					ccor = li.childcontent.getCoordinates();
461					li.childcontent.setStyle ('display', 'none');
462				}
463
464				var ml = 0;
465				var l = lcor.left;
466				var r = l + ccor.width;
467				if (this.wrapper) {
468					var wcor = this.wrapper.getCoordinates();
469					l = l - wcor.left;
470					r = wcor.right - r + 10;
471				} else {
472					r = window.getWidth() - r + 10;
473				}
474				if (l < 0 || l+r < 0) {
475					ml = - l;
476				} else if (r < 0) {
477					ml = r;
478				}
479				if (ml != 0) li.childcontent.setStyle ('margin-left', ml);		
480                if (mtop = li.getElement('.childcontent-inner')) {
481                    var topleft = lcor.left - mtop.getCoordinates().left + lcor.width / 2 - 4.5; /*4.5 = width of arrow image / 2*/
482                    mtop.setStyle('background-position', topleft + "px top");
483                }                
484			} else {
485				//check position
486				var lcor = li.getCoordinates();						
487				var ccor = li.childcontent.getCoordinates();
488				if(!ccor.width)
489				{
490					li.childcontent.setStyle ('display', 'block');
491					ccor = li.childcontent.getCoordinates();
492					li.childcontent.setStyle ('display', 'none');
493				}
494				var mr = 0;
495				var r = lcor.right;
496				var l = r - ccor.width;
497				if (this.wrapper) {
498					var wcor = this.wrapper.getCoordinates();
499					l = l - wcor.left + 10;
500					r = wcor.right - r + 10;
501				} else {
502					r = window.getWidth() - r + 10;
503				}
504				if (r < 0 || l+r < 0) {
505					mr = - r;
506				} else if (l < 0) {
507					mr = l;
508				}
509				if (mr != 0) li.childcontent.setStyle ('margin-right', mr);
510                if (mtop = li.getElement('.childcontent-inner')) {
511                    var topleft = lcor.left - mtop.getCoordinates().left + lcor.width / 2 - 4.5;
512                    mtop.setStyle('background-position', topleft + "px top");
513                }
514			}
515		} else {
516			//check if it's out of view-port
517			var lcor = li.getCoordinates();
518			var ccor = li.childcontent.getCoordinates();
519			if(!ccor.width)
520			{
521				li.childcontent.setStyle ('display', 'block');
522				ccor = li.childcontent.getCoordinates();
523				li.childcontent.setStyle ('display', 'none');
524			}
525			var ml = 0;
526			var l = ccor.left;
527			var r = l + ccor.width;
528			if (this.wrapper) {
529				var wcor = this.wrapper.getCoordinates();
530				l = l - wcor.left;
531				r = wcor.right - r + 10;
532			} else {
533				r = window.getWidth() - r + 10;
534			}
535			if (r < 0) {
536				//change the direction and position for submenu
537				li.childcontent.setStyle ('margin-left', -ccor.width + 20);
538				//li.eff_on['margin-left'] = 0;
539				//li.eff_off['margin-left'] = li._w + 20;
540				li.childcontent_inner.setStyle ('margin-left', li._w + 20);
541                if (mtop = li.getElement('.childcontent-inner')) {
542                    var topleft = lcor.left - mtop.getCoordinates().left + lcor.width / 2 - 4.5; /*4.5 = width of arrow image / 2*/
543                    mtop.setStyle('background-position', topleft + "px top");
544                }
545			}
546		}		
547	}
548});

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.