Skip to content

Instantly share code, notes, and snippets.

@Noble-Mushtak
Created August 8, 2015 16:04
Show Gist options
  • Save Noble-Mushtak/900ae6825bbc0f9f0f4a to your computer and use it in GitHub Desktop.
Save Noble-Mushtak/900ae6825bbc0f9f0f4a to your computer and use it in GitHub Desktop.
Lightweight Dropdowns:
//The event names. These change according to whether or not the user is on a mobile device, or specifically a Windows Phone.
var isIEMobile = navigator.userAgent.indexOf("IEMobile") != -1;
var isMobile = navigator.userAgent.indexOf("Mobile") != -1;
var mouseevents = {
click: "click",
mousedown: isIEMobile ? "pointerdown" : (isMobile ? "touchstart" : "mousedown"),
mouseup: isIEMobile ? "pointerup" : (isMobile ? "touchend" : "mouseup"),
mousemove: isIEMobile ? "pointermove" : (isMobile ? "touchmove" : "mousemove"),
mouseenter: isIEMobile ? "pointerenter" : (isMobile ? "touchenter" : "mouseenter"),
mouseleave: isIEMobile ? "pointerleave" : (isMobile ? "touchleave" : "mouseleave")
};
//The different dropdown bars for the different tabs.
var dropdowns = [
/*blog:*/ [document.createElement("a"), document.createElement("a")],
/*writings:*/ [document.createElement("span")],
/*code:*/ [document.createElement("a"), document.createElement("a"), document.createElement("a")],
/*otherStuff:*/ [document.createElement("a"), document.createElement("a")]
];
//Here, we set the link, title, and text content of each dropdown.
dropdowns[0][0].href = "/blog/";
dropdowns[0][0].title = "A list of all of the blog posts";
dropdowns[0][0].textContent = "Blog Home";
dropdowns[0][1].href = "/blog/rss-feed.rss";
dropdowns[0][1].title = "An RSS Feed to help you keep up with blog posts";
dropdowns[0][1].textContent = "RSS Feed";
dropdowns[1][0].textContent = "Nothing Yet!";
dropdowns[1][0].title = "Will come eventually!"
dropdowns[2][0].href = "/Code%20Base";
dropdowns[2][0].title = "A place where I keep all of my code";
dropdowns[2][0].textContent = "Code Base";
dropdowns[2][1].href = "/Projects";
dropdowns[2][1].title = "A bunch of projects hosted on this site.";
dropdowns[2][1].textContent = "Projects";
dropdowns[2][2].href = "/HTML%20Lessons";
dropdowns[2][2].title = "Learn HTML and CSS from this website!";
dropdowns[2][2].textContent = "HTML Lessons";
dropdowns[3][0].href = "/Chat%20Center";
dropdowns[3][0].title = "A place where you can chat with everyone else on the site!";
dropdowns[3][0].textContent = "Chat Center";
dropdowns[3][1].href = "/Online%20Stuff";
dropdowns[3][1].title = "The random things I do while on the Internet";
dropdowns[3][1].textContent = "Online Stuff";
//All of the tabs in the heading.
var tabs = document.querySelectorAll("#tabs > *");
//The parent node of the tabs.
var container = tabs[0].parentNode;
//An invisible element with an absolute position that we copy for each dropdown.
var absoluteDiv = document.createElement("div");
absoluteDiv.className = "col-md-2 col-xs-2";
absoluteDiv.style.position = "absolute";
absoluteDiv.style.display = "none";
absoluteDiv.style.opacity = 1;
//Counters that store the return of a setTimeout() function to be passed into clearTimeout() if necessary.
var counters = [
/*blog:*/ null,
/*writings:*/ null,
/*code:*/ null,
/*otherStuff:*/ null
];
//An event function generator that shows a bunch of absolutely position divs such that they look like a dropdown bar.
var dropdownShowEvent = function(index) {
return function() {
if (counters[index] != null) {
clearTimeout(counters[index]);
counters[index] = null;
}
for (var i = 0; i < dropdowns[index].length; i++) dropdowns[index][i].style.display = "block";
};
};
//A utility function for dropdownHideEvent that hides a dropdown bar.
var hideDropdowns = function(index) {
var elems = dropdowns[index];
counters[index] = null;
for (var i = 0; i < elems.length; i++) elems[i].style.display = "none";
};
//An event function generator that fades out and hides dropdown bars if the mouse isn't over them.
var dropdownHideEvent = function(index) {
return function eventHandler() {
if (counters[index]) {
hideDropdowns(index);
} else {
counters[index] = setTimeout(eventHandler, 200);
}
};
};
//This initalized the dropdown bars by creating them and giving both the tabs and them event handlers.
for (var i = 0; i < dropdowns.length; i++) {
var eventShowHandler = dropdownShowEvent(i);
var eventHideHandler = dropdownHideEvent(i);
//Only need to initiate capture on mobile devices
tabs[i].addEventListener(isMobile ? mouseevents.mousedown : mouseevents.mouseenter, eventShowHandler, isMobile);
//On mobile devices, we want the dropdown menus to dispear when we click somewhere else. Otherwise, we just hide it when the mouse has left the dropdown bar.
if (isMobile) document.body.addEventListener(mouseevents.mousedown, eventHideHandler, true);
else tabs[i].addEventListener(mouseevents.mouseleave, eventHideHandler);
for (var j = 0; j < dropdowns[i].length; j++) {
var dropdown = absoluteDiv.cloneNode();
dropdown.appendChild(dropdowns[i][j]);
dropdowns[i][j] = dropdown;
dropdown.addEventListener(isMobile ? mouseevents.mousedown : mouseevents.mouseenter, eventShowHandler);
if (!isMobile) dropdown.addEventListener(mouseevents.mouseleave, eventHideHandler);
container.insertBefore(dropdown, container.firstChild);
}
}
var positionDropdowns = function() {
/*This positions the dropdown bars.*/
for (var i = 0; i < dropdowns.length; i++) {
var locationStats = tabs[i].getBoundingClientRect();
var prevLocStats = {
top: locationStats.top+window.pageYOffset,
height: locationStats.height,
left: locationStats.left+window.pageXOffset-0.04*document.body.clientWidth
};
for (var j = 0; j < dropdowns[i].length; j++) {
var dropdown = dropdowns[i][j];
dropdown.style.left = prevLocStats.left+"px";
dropdown.style.top = prevLocStats.top+prevLocStats.height+"px";
prevLocStats.top += prevLocStats.height;
dropdown.style.display = "block";
prevLocStats.height = dropdown.clientHeight;
dropdown.style.display = "none";
}
}
};
//We position the dropdowns in the beginning of the page load and when the window is resized.
positionDropdowns();
window.addEventListener("resize", positionDropdowns);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment