Last active
September 15, 2015 06:44
-
-
Save matesnippets/2b466ca407c587b64e1a to your computer and use it in GitHub Desktop.
JavaSript, Toggle a panel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
define(function() { | |
/** | |
* Toggles a drawer panel | |
* | |
* Click a button and a drawer is shown, click elswhere and it's closed, | |
* open it when element inside the drawer is focused with a keyboard. | |
* | |
* @param {string} trigger ID, class, or element name to the button that toggles the drawer | |
* @param {string} drawer ID, class, or element name to the drawer element | |
* @param {string} drawerParent ID of the drawer parent element | |
* @param {string} activeClass Class name to toggle in the element | |
*/ | |
return function(trigger, drawer, drawerParent, activeClass) { | |
var drawerBare = drawer.replace(/\.|#/g, ''), | |
drawerIsFocused, drawerShower, closest; | |
trigger = document.querySelector(trigger); | |
drawer = document.querySelector(drawer); | |
// The minimalistic closest function | |
closest = function(elem, fn) { | |
return elem && (fn(elem) ? elem : closest(elem.parentNode, fn)); | |
}; | |
// Check if any elements inside the drawer are focused | |
drawerIsFocused = function(e) { | |
// Get the closest | |
var closestEl = closest(e.target, function(elem) { | |
return elem.id === drawerBare; | |
}); | |
if (!closestEl) { | |
drawer.classList.remove(activeClass); | |
} else { | |
drawer.classList.add(activeClass); | |
} | |
}; | |
// Drawer shower/hider | |
drawerShower = function(e) { | |
// Get the closest | |
var closestEl = closest(e.target, function(elem) { | |
return elem.id === drawerParent; | |
}); | |
// If the trigger is clicked | |
if (e.target.id === trigger.id) { | |
drawer.classList.toggle(activeClass); | |
trigger.classList.toggle(activeClass); | |
} | |
// Close if anywhere else is clikced | |
if (!closestEl) { | |
drawer.classList.remove(activeClass); | |
trigger.classList.remove(activeClass); | |
} else { | |
trigger.classList.add(activeClass); | |
} | |
}; | |
// Bind all the function to events | |
if (document.addEventListener) { | |
document.addEventListener('focus', drawerIsFocused, true); | |
document.addEventListener('click', drawerShower); | |
} else { | |
// This is for IE8, it might not work... I haven't tested it | |
document.attachEvent('onfocus', drawerIsFocused); | |
document.attachEvent('onclick', drawerShower); | |
} | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment