Skip to content

Instantly share code, notes, and snippets.

@ffoodd
Last active August 29, 2015 14:18
Show Gist options
  • Save ffoodd/46935b1b0cdb8162f849 to your computer and use it in GitHub Desktop.
Save ffoodd/46935b1b0cdb8162f849 to your computer and use it in GitHub Desktop.
Fly out menu pattern
//
// La fonction qui fait tout
//
function flyOut() {
var menuFlyOut = document.getElementById("flyoutaria"),
lisFlyOut = menuFlyOut.querySelectorAll("> ul > li");
//
// Motif de conception « fly-out »
// @note Motif édité par le WAI
// @see http://www.w3.org/WAI/tutorials/menus/flyout/
//
// Pour chaque sous-menu
Array.prototype.forEach.call(lisFlyOut, function(el, i) {
var liFlyOut = el;
// Au survol
liFlyOut.addEventListener("mouseover", function (e) {
// On ajoute la classe open
this.classList.add("open");
// On met à jour aria-expanded sur le lien enfant direct
this.querySelector("a").setAttribute("aria-expanded", "true");
});
// En sortie du survol
liFlyOut.addEventListener("mouseout", function (e) {
// On supprime la classe open
this.classList.remove("open");
// On met à jour aria-expanded sur le lien enfant direct
this.querySelector("a").setAttribute("aria-expanded", "false");
});
// On lui colle les jolis attributs Aria
liFlyOut.querySelector("a").setAttribute("role", "button");
liFlyOut.querySelector("a").setAttribute("aria-haspopup", "true");
liFlyOut.querySelector("a").setAttribute("aria-expanded", "false");
// Au clic
liFlyOut.querySelector("a").addEventListener("click", function (e) {
var opennav = this.parentNode.classList.contains("open");
// Si le sous-menu est déjà ouvert
if (opennav) {
// On change la valeur de aria-expanded
this.setAttribute("aria-expanded", "false");
// Puis on vire la classe
this.parentNode.classList.remove("open");
} else {
// On change la valeur de aria-expanded
this.setAttribute("aria-expanded", "true");
// Puis on vire la classe
this.parentNode.classList.add("open");
}
e.preventDefault();
return false;
});
// À la pression sur espace
liFlyOut.querySelector("a").addEventListener("keydown", function (e) {
var touche = e.keyCode || e.which;
// Si ça n'est pas la barre « Espace »
if (32 != touche) {
// On ne fait rien
return;
// Sinon
} else if (32 == touche) {
// On délcenche le clic
this.click();
// Et on empêche le comportement stantard
e.preventDefault();
}
}, true);
// Au focus
liFlyOut.querySelector("a").addEventListener("focus", function (e) {
var opennav = this.parentNode.classList.contains("open"),
autre_ouvert = document.querySelector("#flyoutaria .has-submenu.open");
// Si le sous-menu est déjà ouvert
if (!opennav && autre_ouvert) {
// On change la valeur de aria-expanded
autre_ouvert.querySelector("[aria-expanded]").setAttribute("aria-expanded", "false");
// Puis on vire la classe
autre_ouvert.classList.remove("open");
}
});
});
}
};
//
// Événements
//
document.addEventListener("DOMContentLoaded", flyOut);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment