PageSourceSearch

http://oknovknr.ru/t/v1107/images/scripts/s3.menu.allin.js

js oknovknr.ru collected 2026-09-30 03:00:05 UTC 12,448 bytes, 690 lines download raw bytes

1/* masalygin 0.0.2 */
2
3/*
4* ошибки:
5* exitTimeout не всегда работает работает
6*
7* */
8
9'use strict';
10
11(function (factory) {
12
13	if (typeof define === 'function' && define.amd) {
14
15		define(['jquery', 's3/misc/math/0.0.1/s3.math', 's3/misc/eventable/0.0.1/s3.eventable'], factory);
16
17	} else {
18
19		factory(jQuery, s3Math);
20
21	}
22
23})(function ($, math) {
24
25	var points;
26
27	function debug() {
28
29		var menu = this;
30
31		if (!menu.settings.debug && document.location.search.indexOf('test') == -1) {
32			return false;
33		}
34
35		if (!points) {
36
37			points = {};
38
39			$.each(['a', 'b', 'c'], function (key, value) {
40
41				var attr = {
42					id: 's3-menu-allin-point-' + value,
43					'class': 's3-menu-allin-point',
44					html: value
45				};
46
47				points[value] = $('<div></div>', attr);
48
49				$(document.body).append(points[value]);
50
51			});
52
53		}
54
55		$.each(points, function (name, point) {
56
57			point.css({
58				left: menu.triangle[name].x,
59				top: menu.triangle[name].y
60			});
61
62		});
63
64	}
65
66	$.s3MenuAllInTypes = {
67
68		_popup: {
69
70			activate: function (params) {
71
72				var $siblings = params.$item.siblings();
73				params.$item.addClass(this.settings.activeClass);
74				$siblings.removeClass(this.settings.activeClass);
75				this.hide($siblings.children('ul'));
76				this.show(params.$sub);
77				this.hide(params.$sub.find('ul'));
78
79			},
80
81			deactivate: function (params) {
82
83				params.$item.removeClass(this.settings.activeClass);
84				this.hide(params.$sub);
85
86			},
87
88			exit: function () {
89
90				this.$li.removeClass(this.settings.activeClass);
91				this.hide(this.$ul);
92
93			}
94
95		},
96
97		bottom: function (menu) {
98
99			menu.on('activate', function (params) {
100
101				var $sub = params.$sub;
102
103				if (!$sub.length) {
104					return;
105				}
106
107				var winWidth = $(window).width();
108				var $item = params.$item;
109				var isHidden = $sub.is(':hidden');
110
111				$sub.show();
112
113				var iPos = $item.position();
114				var iOffset = $item.offset();
115				var iWidth = $item.width();
116				var sWidth = $sub.width();
117				var sPos = {};
118
119				var b = this.triangle.b;
120				var c = this.triangle.c;
121
122				var left;
123				var revert = false;
124
125				if (params.level === 1) {
126
127					left = iOffset.left + sWidth;
128
129					if (left > winWidth) {
130
131						sPos.left = iPos.left + iWidth - sWidth;
132
133					} else {
134
135						sPos.left = iPos.left;
136
137					}
138
139					sPos.top = iPos.top + $item.height();
140
141				} else {
142
143					left = iOffset.left + iWidth + sWidth;
144
145					if (left > winWidth) {
146
147						sPos.left = iPos.left - sWidth;
148						revert = true;
149
150					} else {
151
152						sPos.left = iPos.left + iWidth;
153
154					}
155
156					sPos.top = iPos.top;
157
158				}
159
160				$sub.css(sPos);
161
162				var sOffset = $sub.offset();
163
164				if (params.level === 1) {
165
166					b.y = c.y = sOffset.top;
167					b.x = sOffset.left;
168					c.x = sOffset.left + sWidth;
169
170				} else {
171
172					b.y = sOffset.top;
173					c.y = sOffset.top + $sub.height();
174					b.x = c.x = revert ? sOffset.left + sWidth : sOffset.left;
175
176				}
177
178				if (isHidden) {
179					$sub.hide();
180				}
181
182
183			});
184
185			menu.on(this._popup);
186
187		},
188
189		top: function (menu) {
190
191			menu.on('activate', function (params) {
192
193				var $sub = params.$sub;
194
195				if (!$sub.length) {
196					return;
197				}
198
199				var winWidth = $(window).width();
200				var $item = params.$item;
201				var isHidden = $sub.is(':hidden');
202
203				$sub.show();
204
205				var iPos = $item.position();
206				var iOffset = $item.offset();
207				var iWidth = $item.width();
208				var iHeight = $item.height();
209				var sWidth = $sub.width();
210				var sHeight = $sub.height();
211				var sPos = {};
212
213				var b = this.triangle.b;
214				var c = this.triangle.c;
215
216				var left;
217				var revert = false;
218
219				if (params.level === 1) {
220
221					left = iOffset.left + sWidth;
222
223					if (left > winWidth) {
224
225						sPos.left = iPos.left + iWidth - sWidth;
226
227					} else {
228
229						sPos.left = iPos.left;
230
231					}
232
233					sPos.top = iPos.top - sHeight;
234
235				} else {
236
237					left = iOffset.left + iWidth + sWidth;
238
239					if (left > winWidth) {
240
241						sPos.left = iPos.left - sWidth;
242						revert = true;
243
244					} else {
245
246						sPos.left = iPos.left + iWidth;
247
248					}
249
250					sPos.top = iPos.top - sHeight + iHeight;
251
252				}
253
254				$sub.css(sPos);
255
256				var sOffset = $sub.offset();
257
258				if (params.level === 1) {
259
260					b.y = c.y = sOffset.top + sHeight;
261					b.x = sOffset.left;
262					c.x = sOffset.left + sWidth;
263
264				} else {
265
266					b.y = sOffset.top;
267					c.y = sOffset.top + $sub.height();
268					b.x = c.x = revert ? sOffset.left + sWidth : sOffset.left;
269
270				}
271
272				if (isHidden) {
273					$sub.hide();
274				}
275
276			});
277
278			menu.on(this._popup);
279
280		},
281
282		right: function (menu) {
283
284			menu.on('activate', function (params) {
285
286				var $sub = params.$sub;
287
288				if (!$sub.length) {
289					return;
290				}
291
292				var winWidth = $(window).width();
293				var $item = params.$item;
294				var isHidden = $sub.is(':hidden');
295
296				$sub.show();
297
298				var iPos = $item.position();
299				var iOffset = $item.offset();
300				var iWidth = $item.width();
301				var sWidth = $sub.width();
302				var sPos = {};
303
304				var b = this.triangle.b;
305				var c = this.triangle.c;
306
307				var left;
308				var revert = false;
309
310				left = iOffset.left + iWidth + sWidth;
311
312				sPos.top = iPos.top;
313
314				if (left > winWidth) {
315
316					sPos.left = iPos.left - sWidth;
317					revert = true;
318
319				} else {
320
321					sPos.left = iPos.left + iWidth;
322
323				}
324
325				$sub.css(sPos);
326
327				var sOffset = $sub.offset();
328
329				b.y = sOffset.top;
330				c.y = sOffset.top + $sub.height();
331				b.x = c.x = revert ? sOffset.left + sWidth : sOffset.left;
332
333				if (isHidden) {
334					$sub.hide();
335				}
336
337
338			});
339
340			menu.on(this._popup);
341
342		},
343
344		left: function (menu) {
345
346			menu.on('activate', function (params) {
347
348				var $sub = params.$sub;
349
350				if (!$sub.length) {
351					return;
352				}
353
354				var $item = params.$item;
355				var isHidden = $sub.is(':hidden');
356
357				$sub.show();
358
359				var iPos = $item.position();
360				var iOffset = $item.offset();
361				var iWidth = $item.width();
362				var sWidth = $sub.width();
363				var sPos = {};
364
365				var b = this.triangle.b;
366				var c = this.triangle.c;
367
368				var left;
369				var revert = false;
370
371				left = iOffset.left - sWidth;
372
373				sPos.top = iPos.top;
374
375				if (left < 0) {
376
377					sPos.left = iPos.left + sWidth;
378					revert = true;
379
380				} else {
381
382					sPos.left = iPos.left - iWidth;
383
384				}
385
386				$sub.css(sPos);
387
388				var sOffset = $sub.offset();
389
390				b.y = sOffset.top;
391				c.y = sOffset.top + $sub.height();
392				b.x = c.x = revert ? sOffset.left : sOffset.left + sWidth;
393
394				if (isHidden) {
395					$sub.hide();
396				}
397
398			});
399
400			menu.on(this._popup);
401
402		},
403
404		dropdown: function (menu, selector) {
405
406			selector = selector || 'a';
407
408			menu.$el.on({
409
410				click: function () {
411
412					var $a = $(this);
413					var $item = $a.closest('li');
414					var $sub = $item.children('ul');
415
416					if (!$sub.length) {
417						return true;
418					}
419
420					if ($sub.is(':animated')) {
421						return false;
422					}
423
424					if ($sub.is(':hidden')) {
425
426						menu.show($sub, function () {
427							$a.addClass(menu.settings.openClass);
428						});
429
430					} else {
431
432						menu.hide($sub, function () {
433							$a.removeClass(menu.settings.openClass);
434						});
435
436					}
437
438					return false;
439
440				}
441
442			}, selector);
443
444		},
445
446		_dropdownPlus: function(menu, direction) {
447
448			var $el = menu.$el.children('li');
449
450			var dropDownMenu = $.extend({}, menu, {
451				$el: $el
452			});
453
454			$.s3MenuAllInTypes.dropdown(dropDownMenu, '> a');
455
456			$el.children('ul').s3MenuAllIn($.extend({}, menu.settings, {type: direction}));
457
458		},
459
460		'dropdown+left': function (menu) {
461			this._dropdownPlus(menu, 'left');
462		},
463
464		'dropdown+right': function(menu) {
465			this._dropdownPlus(menu, 'right');
466		}
467
468	};
469
470	$.fn.s3MenuAllIn = function (settings) {
471
472		settings = $.extend({
473
474			deviation: 10,
475			type: 'right',
476			exitTimeout: 250,
477			activateTimeout: 0,
478			deactivateTimeout: 100,
479			exclude: 'ul',
480			debug: false,
481			showFn: $.fn.show,
482			showTime: 0,
483			hideFn: $.fn.hide,
484			hideTime: 0,
485			activeClass: 's3-menu-allin-active',
486			hasClass: 's3-menu-allin-has',
487			openClass: 's3-menu-allin-open'
488
489		}, settings);
490
491		return this.each(function() {
492
493			var $el = $(this);
494
495			var menu = $.s3Eventable({
496
497				settings: settings,
498				triangle: new math.Triangle({}, {}, {}),
499				$el: $el,
500				$li: $el.find('li'),
501				$ul: $el.find('ul'),
502				isBlocked: false,
503				isExit: true,
504				active: {}
505
506			});
507
508			$.each(['show', 'hide'], function (key, value) {
509				menu[value] = function ($el, callback) {
510					if ($el.length) {
511						$el.stop(true, true);
512						this.settings[value + 'Fn'].call($el, this.settings[value + 'Time'], callback || $.noop);
513					}
514				};
515			});
516
517			if (settings.hasClass) {
518				menu.$ul.parent('li').addClass(settings.hasClass);
519			}
520
521			$(document).on('mousemove', function(e) {
522
523				if (menu.isBlocked) {
524
525					var $target = $(e.target);
526					var $item = $target.not(settings.exclude).closest('li');
527					var hasPoint = menu.triangle.hasPoint({x: e.pageX, y: e.pageY}, settings.deviation);
528					var isMenu = !!menu.$el.has($target).length;
529					var isSub = false;
530
531					if ($item.length && menu.active.$sub) {
532						isSub = $item.closest('ul').get(0) === menu.active.$sub.get(0);
533					}
534
535					if (isMenu) {
536
537						menu.isExit = false;
538						clearTimeout(menu.exitTimeoutId);
539						clearTimeout(menu.deactivateTimeoutId);
540
541					}
542
543					if (isSub) {
544
545						menu.isBlocked = false;
546						$item.trigger('mouseenter');
547
548					} else if (isMenu) {
549
550						var params = $.extend({}, menu.active);
551
552						if (hasPoint) {
553
554							(function(params) {
555
556								menu.deactivateTimeoutId = setTimeout(function () {
557
558									menu.isBlocked = false;
559									menu.trigger('deactivate', params);
560									$item.trigger('mouseenter');
561
562								}, settings.deactivateTimeout);
563
564							})(params);
565
566						} else {
567
568							menu.isBlocked = false;
569							menu.trigger('deactivate', params);
570							$item.trigger('mouseenter');
571
572						}
573
574					} else {
575
576						if (hasPoint) {
577
578							clearTimeout(menu.exitTimeoutId);
579							menu.exitTimeoutId = setTimeout(function () {
580
581								menu.isBlocked = false;
582								menu.trigger('exit');
583
584							}, settings.deactivateTimeout);
585
586						} else {
587
588//							if (!menu.isExit) {
589
590								menu.isExit = true;
591								menu.isBlocked = false;
592
593								clearTimeout(menu.exitTimeoutId);
594								menu.exitTimeoutId = setTimeout(function () {
595
596									if (menu.isExit) {
597										console.log(2);
598										menu.trigger('exit');
599									}
600
601
602								}, settings.exitTimeout);
603
604//							}
605
606						}
607
608					}
609
610				}
611
612			});
613
614			menu.$el.on({
615
616				mouseenter: function(e) {
617
618					e.stopPropagation();
619					menu.isExit = false;
620
621					if (menu.isBlocked) {
622						return;
623					}
624
625					var $item = $(this);
626					var $sub = $item.children('ul');
627					var $parents = $sub.parentsUntil(menu.$el, 'li');
628
629					(function(params) {
630
631						clearTimeout(menu.activateTimeoutId);
632						menu.activateTimeoutId = setTimeout(function () {
633
634							if (menu.isExit) {
635								return;
636							}
637
638							menu.isBlocked = false;
639							menu.trigger('activate', params);
640							menu.active = params;
641
642						}, menu.settings.activateTimeout);
643
644					})({
645						$item: $item,
646						$sub: $sub,
647						$parents: $parents,
648						$ul: $item.parent(),
649						level: $parents.length
650					});
651
652				},
653
654				mouseleave: function(e) {
655
656					e.stopPropagation();
657
658					if (menu.isBlocked) {
659						return;
660					}
661
662					menu.triangle.a.x = e.pageX;
663					menu.triangle.a.y = e.pageY;
664					menu.isBlocked = true;
665
666					var $item = $(this);
667					var $sub = $item.children('ul');
668					var $parents = $sub.parentsUntil(menu.$el, 'li');
669
670					menu.active = {
671						$item: $item,
672						$sub: $sub,
673						$parents: $parents,
674						$ul: $item.parent(),
675						level: $parents.length
676					};
677
678				}
679
680			}, 'li');
681
682			$.s3MenuAllInTypes[settings.type](menu);
683			menu.on('activate', debug);
684
685		});
686
687	};
688
689
690});

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.