PageSourceSearch

https://www.flikvlooi.co.za/js/navigation.r40242.js

js flikvlooi.co.za collected 2026-10-04 03:37:14 UTC 10,607 bytes, 329 lines download raw bytes

1// $Id: navigation.js 39999 2026-05-18 09:46:14Z brendon $
2
3//--- CSS navigation menu -------------------------------------
4// Requires: inArray(), multipleClasses()
5
6var cssMenus = {
7	delay: 180,
8	timer: 100,
9	LIs: [],
10	ULs: [],
11	revertLIs: [],
12	revertULs: [],
13	streamLIs: [],
14	streamULs: [],
15	activeLI: null,
16	activeUL: null,
17	secondLevel: null,
18	headerOuterHeight: 0,
19	stickyHeaderSpacer: 0,
20	
21	clearStreamLI: function () {
22		// remove "expanded" class from list items
23		for (var x = 0; x < this.streamLIs.length; x++) {
24			multipleClasses("remove", this.streamLIs[x], "expanded");
25		}
26		
27		this.streamLIs = [];
28	},
29	
30	hideStreamUL: function () {
31		// hide lists
32		for (var x = 0; x < this.streamULs.length; x++) {
33			if (typeof jQuery != 'undefined') {
34				$(this.streamULs[x]).slideUp(this.delay);
35			} else {
36				this.streamULs[x].style.display = "none";
37			}
38		}
39		
40		this.streamULs = [];
41	},
42	
43	showActive: function (obj, dropmenuID) {
44		// add "expanded" class to the active list item, set activeLI
45		multipleClasses("add", obj, "expanded");
46		// shows expanded arrow onClick
47		$(".js ul.firstLevelWrapper li.expanded div.arrow").css('display','block');
48		
49		this.activeLI = obj;
50		
51		// if list item not already in streamLIs, add to streamLIs
52		if (!inArray(this.activeLI, this.streamLIs)) {
53			this.streamLIs[this.streamLIs.length] = this.activeLI;
54		}
55		
56		// if a submenu list exists and is not already active, then show submenu list
57		if ((dropmenuID != null) && (dropmenuID > "") && (dropmenuID != this.activeUL)) {
58			// show new list, set activeUL
59			if (typeof jQuery != 'undefined') {
60				$("#" + dropmenuID).slideDown(this.delay);
61			} else {
62				document.getElementById(dropmenuID).style.display = "block";
63			}
64			this.activeUL = document.getElementById(dropmenuID);
65			
66			// if list not already in streamULs and not firstLevel, add to streamULs
67			if (!inArray(this.activeUL, this.streamULs) && !multipleClasses("check", this.activeUL, "firstLevelWrapper")) {
68				this.streamULs[this.streamULs.length] = this.activeUL;
69			}
70		}
71	},
72	
73	dropit: function (obj, dropmenuID, displayMenu) {
74		// actions for list items
75		// issue: clicking outside span, doesnt scroll up
76		var checkActiveLI = (this.activeLI == obj);
77		if (this.streamLIs.length == 0) {
78			if (!checkActiveLI || displayMenu) {
79				cssMenus.hide(obj, false);
80			}
81			if (!displayMenu) {
82				cssMenus.showActive(obj, dropmenuID);
83			}
84		} else {
85			cssMenus.hide(obj, true);
86			if (!checkActiveLI) {
87				// cssMenus.showActive(obj, dropmenuID);
88				setTimeout(function() { cssMenus.showActive(obj, dropmenuID); }, this.timer);
89			}
90		}
91	},
92	
93	hide: function (obj, timeOut) {
94		// if list item is on firstLevelWrapper
95		if (multipleClasses("check", obj.parentNode, "firstLevelWrapper")) {
96			cssMenus.hideStreamUL();
97			if (timeOut) {
98				// cssMenus.clearStreamLI();
99				setTimeout(function() { cssMenus.clearStreamLI(); }, this.timer);
100			} else {
101				cssMenus.clearStreamLI();
102			}
103		}
104	},
105	
106	init: function () {
107		// build obects of all unordered lists and list items in the navigation div
108		if (document.getElementById(arguments[0])) {
109			this.ULs = document.getElementById(arguments[0]).getElementsByTagName("ul");
110			this.LIs = document.getElementById(arguments[0]).getElementsByTagName("li");
111			
112			// build array of active lists to revert to
113			for (var x = 0; x < this.ULs.length; x++) {
114				// if list class contains "expanded" and not "firstLevelWrapper"
115				if (multipleClasses("check", this.ULs[x], "expanded")) {
116					if (!multipleClasses("check", this.ULs[x], "firstLevelWrapper")) {
117						this.revertULs[this.revertULs.length] = this.ULs[x];
118						this.streamULs[this.streamULs.length] = this.ULs[x];
119					}
120				}
121			}
122			
123			// set active list
124			//this.activeUL = this.revertULs[this.revertULs.length-1];
125			
126			// build array of active list items to revert to
127			for (var x = 0; x < this.LIs.length; x++) {
128				// if list item class contains "expanded"
129				if (multipleClasses("check", this.LIs[x], "expanded")) {
130					this.revertLIs[this.revertLIs.length] = this.LIs[x];
131					this.streamLIs[this.streamLIs.length] = this.LIs[x];
132				}
133			}
134			
135			// set active list item
136			//this.activeLI = this.revertLIs[this.revertLIs.length-1];
137			this.headerOuterHeight = $("#header .container:first").outerHeight(true);
138			setTimeout( function() {
139				cssMenus.stickyHeaderSpacer = $(".stickyHeader").outerHeight(true);
140			});
141
142			// create click event for all list items
143			for (var x = 0; x < this.LIs.length; x++) {
144				if (multipleClasses("check", this.LIs[x].parentNode, "firstLevelWrapper")) {
145					var that = this;
146					
147					if ($(this.LIs[x]).hasClass("displaySecondLevel")) {
148						var dropmenuID = $(this.LIs[x]).attr("id") + "Menu";
149						cssMenus.dropit(this.LIs[x], dropmenuID);
150					}
151					
152					$(this.LIs[x]).find("a").on('click', function(e) {
153						var addedClassModalOpen = false;
154						var isHeaderFoldout = false;
155
156						// Close the logintab when switching between first level nav items
157						if ($("#header .headerFoldout").css("display") == "block") {
158							// since the header becomes overlay
159							// restore the content to the correct position
160							$("#navigation").animate({
161								top: "0px"
162							}, "fast");
163
164							loginDropdown($("div.loginTab"));
165							isHeaderFoldout = true;
166						}
167
168						// Close the languageTab when switching between first level nav items
169						if ($('.languageDropdown').is(":visible")) {
170							$('.languageDropdown').slideUp('fast');
171						}
172
173						if ($("html, body").hasClass("modal-open") && !isHeaderFoldout) {
174							addedClassModalOpen = true;
175						}
176
177						if (stickyHeaderBar) {
178							if (addedClassModalOpen) {
179								$("html, body").removeClass("modal-open");
180							} else {
181								$("html, body").addClass("modal-open");
182							}
183						}
184
185						if ($(this).hasClass("jewelButton")) {
186							var _this = this.parentNode.parentNode;
187						} else {
188							var _this = this.parentNode;
189						}
190
191						e.preventDefault();
192						e.stopPropagation();
193
194						var target = e.target,
195							tagName = $(target).prop('tagName'),
196							displayMenu = ( $(_this).hasClass("expanded") && tagName == "A" ),
197							fixedSection = $(_this).attr("id"),
198							elScroll = $("#"+fixedSection+"Menu");
199
200						// check if releaseCode.stickyHeaderBar is activated
201						if (stickyHeaderBar) {
202							// Make the nav dropdown section scrollable, if dropdown section is visible
203							if (elScroll.css('display') == "none") {
204								var stickyHeaderSpacer = $(".stickyHeader").outerHeight(true);
205								resizeNavMenu(elScroll, cssMenus.stickyHeaderSpacer);
206							}
207						}
208
209						//Prepare for double click, continue to clickHandler doesn't come soon enough
210						clearTimeout(_this.clickTimeout);
211						
212						var pendingClick = function () {
213							var dropmenuID = _this.firstChild.getAttribute("rel");
214							that.secondLevel = document.getElementById(dropmenuID);
215							
216							// if menuItem has no children, make primary menuItem clickable
217							if (that.secondLevel != null) {
218								cssMenus.dropit(_this, dropmenuID, displayMenu);
219							} else {
220								cssMenus.redirect(_this);
221							}
222						};
223						_this.clickTimeout = setTimeout(pendingClick, that.delay);
224					});
225					
226					$(this.LIs[x]).find("a").on('dblclick', function (e) {
227						var _this = this.parentNode;
228						clearTimeout(_this.clickTimeout);
229						cssMenus.redirect(_this);
230					});
231				}
232			}
233		}
234	},
235	
236	redirect: function (obj) {
237		// close dropdown before redirecting
238		cssMenus.hide(obj, true);
239		var redirectURL = $(obj).find("a").attr("href");
240		window.location.href = redirectURL;
241	}
242}
243
244$(document).ready(function(){
245	// executed at page load
246	cssMenus.init("navigation");
247	
248	// able to close the active dropdown by clicking outside the navigation area
249	// close the active dropdown before loading a page
250	$('body').on("click", function(e) {
251		var hideSecondLevel = false,
252			target = $(e.target);
253
254		if (target.closest("div#navigation").length === 0) {
255			hideSecondLevel = true;
256		} else {
257			if (target.is("a")) {
258				hideSecondLevel = true;
259			}
260		}
261		
262		if (hideSecondLevel) {
263			var scrollTop = $(window).scrollTop();
264			$("ul.firstLevelWrapper").children().each(function() {
265				if ($(this).hasClass("expanded")) {
266					cssMenus.hide($(this)[0], true);
267					$("html, body").removeClass("modal-open");
268				}
269			});
270		}
271	});
272});
273
274$(document).ready(function() {
275	// when the first level page loads, this code applies to the menu element that is open and which needs to scroll
276	// these styles are otherwise applied when the user clicks on a navigation item. Without them, the page jumps when you try to scroll
277	setTimeout(function() {
278		if (stickyHeaderBar) {
279			var menuElement = $("#navigation").find(".secondLevelWrapper.expanded");
280			if (menuElement.length) {
281				var stickyHeaderSpacer = $(".stickyHeader").outerHeight(true);
282				resizeNavMenu(menuElement, stickyHeaderSpacer);
283			}
284		}
285	});
286});
287
288function resizeNavMenu (menuElement, stickyHeaderSpacer) {
289	var	screenHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
290		elScroll = menuElement,
291		scrollHeight = 0;
292	
293	// find the distance from the top of the stickyHeader to the top of the browsers viewport
294	var stickyHeader = $(".stickyHeader").get(0);
295	if (stickyHeader) {
296		var stickyHeaderRect = stickyHeader.getBoundingClientRect();
297		stickyHeaderSpacer += stickyHeaderRect.top;
298	}
299
300	// there is no real height available
301	// temporarily show it invisibly
302	elScroll.css({display:'block', visibility:'hidden', position:'absolute'});
303	scrollHeight = elScroll.get(0).scrollHeight;
304	// restore if needed
305	elScroll.css({display:'none', visibility:'', position:''});
306
307	if (mobileBrowser) {
308		scrollHeight = (screenHeight - stickyHeaderSpacer);
309	} else {
310		if ((stickyHeaderSpacer + scrollHeight) > screenHeight) {
311			scrollHeight = (screenHeight - stickyHeaderSpacer);
312		}
313	}
314
315	elScroll.css({"height":scrollHeight + "px", "overflow":"auto"});
316	// disable scrolling in the background, this prevents the stuttering
317	$("html, body").addClass("modal-open");
318}
319
320// banners that appear above the sticky container, need to calculate the height of these elements
321// if element must be included in the sticky container (sticky_header.html)
322function getExtraStickyHeaderHeight () {	
323	var stickyHeaderSpacer = 0;
324	var stickyElements = document.querySelectorAll('#adSlot_header, #thirdPartyHeader, .smartbanner, #siteSwitcher');
325	stickyElements.forEach(function(stickyElement) {
326		stickyHeaderSpacer += stickyElement.offsetHeight;
327	});
328	return stickyHeaderSpacer;
329}

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.