PageSourceSearch

https://signup.eqtiming.com/Templates/QuickSystems/qui/qleafmenu/qleafmenu.js?1720620199

js eqtiming.com collected 2026-09-24 09:25:10 UTC 4,227 bytes, 164 lines download raw bytes

1"use strict";
2
3/**
4 * Endnode-menu for mobile devices, only one open at a time
5 *
6 * Reads structure from a list and displays one layer at a time until user
7 * reaches an endnode or chooses to land on currently open inner node.
8 *
9 * Usage:
10 * -Call qui.qLeafMenu.init() in document load
11 * -any anchor with .qLeafMenuRoot that is clicked opens the ssociated menu with these parameters:
12 *      data-qMenuSrc : jQuery selector for finding the menu list data
13 *
14 **/
15
16var qui = qui || {};
17
18qui.qLeafMenu = (function () {
19	var resizeTimer = null;
20	var resizeDelay = 100;
21	var wrapper = $('<div class="qLeafMenu"></div>');
22	var srcAttr = "data-qLeafMenuSrc";
23	var activeMenu = null;
24
25	var init = function () {
26		var bod = $("body");
27		bod.on("click", "a.qLeafMenuRoot", toggleMenu);
28		bod.on("click", "div.qLeafMenu a.branch", branchClick);
29		bod.on("click", "div.qLeafMenu a.leaf", leafClick);
30		bod.on("click", "div.qLeafMenu a.back", backClick);
31		bod.on("transitionend", "div.qLeafMenu ul", transitionEnd);
32
33		// if click outside opened menu
34		bod.on("click", function (event) {
35			if (activeMenu === null) {
36				return;
37			}
38			if (!$(event.target).closest("div.qLeafMenu, a.menu.qLeafMenuRoot").length) {
39				$("div.qLeafMenu").removeClass("open");
40				close();
41			}
42		});
43
44		// check for window size changes, with a delay to prevent overeager calculations
45		$(window).resize(function (event) {
46			clearTimeout(resizeTimer);
47			resizeTimer = setTimeout(update, resizeDelay);
48		});
49
50		$(document).on('scroll', scroll);
51	};
52	
53	var update = function () {
54		if (!activeMenu) return;
55		var button = activeMenu.data("root");
56		var offset = button.offset();
57
58		var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
59		var newTop = Math.floor(offset.top + button.outerHeight(true));
60		
61		activeMenu.css('top', newTop + "px");
62	};
63
64	var scroll = function () {
65		if (!activeMenu) return;
66		// only update menu position on scroll if there is a gap between top of menu and bottom of button
67		var button = activeMenu.data("root");
68		var buttonoffset = button.offset();
69		var menuoffset = activeMenu.offset();
70
71		if (buttonoffset.top + button.height() < menuoffset.top) {
72			update();
73		}
74	}
75	
76	var toggleMenu = function (evt) {
77		var button = $(this);
78		if (!!activeMenu) {
79			var activeMenuButton = activeMenu.data("root");
80			button.removeClass("open");
81			close();
82			if (activeMenuButton.is(button)) {
83				return;
84			}
85		}
86		
87		open.call(this, evt);
88	};
89	
90	var close = function () {
91		activeMenu.remove();
92		activeMenu = null;
93	};
94	
95	var open = function (evt) {
96		var button = $(this);
97		var src = button.attr(srcAttr);
98		var inner = $(src).clone();
99
100		activeMenu = wrapper.clone();
101		activeMenu.append(inner);
102		activeMenu.data("root", button);
103		activeMenu.find("li > ul").hide();
104		$("body").append(activeMenu);
105		inner.show();
106		setTimeout(function () {
107			activeMenu.addClass("open");
108			button.addClass("open");
109		}, 0);
110
111		update();
112	};
113	
114	var branchClick = function (evt) {
115		evt.preventDefault();
116		var button = $(this);
117		var submenu = button.siblings("ul");
118		var currentmenu = button.closest("ul");
119		currentmenu.addClass("faded");
120		submenu.addClass("closed")
121		submenu.show();
122		setTimeout(function () {
123			submenu.removeClass("closed").addClass("open");
124			if (submenu.height() > currentmenu.height()) {
125				activeMenu.css("min-height", submenu.height() + "px");
126			}
127		}, 100);
128	};
129
130	var leafClick = function (evt) {
131		/*evt.preventDefault();
132		var button = $(this);
133		close();*/
134		var button = $(this);
135		var currentmenu = button.closest("ul");
136		toggleMenu.call(currentmenu, evt);
137	};
138
139	var backClick = function (evt) {
140		evt.preventDefault();
141		var button = $(this);
142		
143		var currentmenu = button.closest("ul");
144		var lastmenu = currentmenu.parent().closest("ul");
145		lastmenu.removeClass("faded");
146		var prevlevel = currentmenu.closest("ul");
147		currentmenu.addClass("closed");
148		if (prevlevel.height() < currentmenu.height()) {
149			activeMenu.css("min-height", prevlevel.height() + "px");
150		}
151	};
152
153	var transitionEnd = function (evt) {
154		var submenu = $(this);
155		if (submenu.hasClass("closed")) {
156			submenu.removeClass("open closed");
157		}
158	}
159
160	return {
161		init: init,
162		update: update
163	};
164})();

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.