Browse Source

New "side-menus" component.

Based on the `modals` component.

See example at http://michaelrienstra.com/temporary/ratchet/side-menus.html

The current implementation relies on putting a wrapper (`<div class="side-menu-siblings-wrapper">`) around the `side-menu`s siblings (`<header class="bar">` & `<div class="content">`). I have working code to handle the wrapping of siblings automatically, as well as working code that works without the wrapper (but I realized I was going to have to add more "moving bits" to get the subtle drop shadow to animate without the wrapper).

Minimally tested on Android (Nexus 4) & iOS (iPhone 5).

Happy to do more testing / etc. if this component is of interest.

Attribution: I borrowed a few lines of CSS from http://mmenu.frebsite.nl/ (which is dual licensed under the MIT and GPL licenses).
pull/551/head
Michael Rienstra 11 years ago
parent
commit
c531b128f7
  1. 74
      js/side-menus.js
  2. 49
      sass/side-menus.scss

74
js/side-menus.js

@ -0,0 +1,74 @@
/* ========================================================================
* Ratchet: side-menus.js v2.0.2
* http://goratchet.com/components#sideMenus
* ========================================================================
* Copyright 2014 Connor Sears
* Licensed under MIT (https://github.com/twbs/ratchet/blob/master/LICENSE)
* ======================================================================== */
!(function () {
'use strict';
var findSideMenus = function (target) {
var i;
var sideMenus = document.querySelectorAll('a');
for (; target && target !== document; target = target.parentNode) {
for (i = sideMenus.length; i--;) {
if (sideMenus[i] === target) {
return target;
}
}
}
};
var getSideMenu = function (event) {
var sideMenuToggle = findSideMenus(event.target);
if (sideMenuToggle && sideMenuToggle.hash) {
var sideMenu = document.querySelector(sideMenuToggle.hash);
if (sideMenu && sideMenu.classList.contains('side-menu')) {
return sideMenu;
}
}
};
var getSideMenuSiblings = function (sideMenu) {
var siblings = [].slice.call(sideMenu.parentNode.children);
siblings = siblings.filter(function(val) {
return [sideMenu].indexOf(val) === -1 && val.nodeName !== 'SCRIPT';
});
return siblings;
};
window.addEventListener('touchend', function (event) {
var sideMenu = getSideMenu(event);
if (sideMenu) {
var siblings = getSideMenuSiblings(sideMenu);
var i;
var l;
var hasBlocker = false;
for (i = 0, l = siblings.length; i < l; i++) {
if (!hasBlocker && siblings[i].classList.contains('side-menu-blocker')) {
hasBlocker = true;
}
if (siblings[i].classList.contains('activeSideMenu')) {
siblings[i].classList.remove('activeSideMenu');
siblings[i].classList.add('inactiveSideMenu');
} else {
siblings[i].classList.remove('inactiveSideMenu');
siblings[i].classList.add('activeSideMenu');
}
}
if (hasBlocker === false) {
var blocker = document.createElement('a');
blocker.href = '#' + sideMenu.id;
blocker.classList.add('side-menu-blocker');
sideMenu.parentElement.appendChild(blocker);
siblings.push(blocker);
blocker.classList.add('activeSideMenu');
}
event.preventDefault(); // prevents rewriting url (apps can still use hash values in url)
}
});
}());

49
sass/side-menus.scss

@ -0,0 +1,49 @@
//
// Side menus
// --------------------------------------------------
.side-menu {
position: fixed;
top: 0;
z-index: -1;
width: 80%;
height: 100%;
}
.side-menu-blocker {
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==) transparent;
display: none;
width: 100%;
height: 100%;
position: fixed;
top: 0;
z-index: 999999;
&.activeSideMenu {
display: block;
box-shadow: none;
}
}
.side-menu-siblings-wrapper {
width: 100%;
height: 100%;
/* Alternate approach, as per BODY:
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
*/
}
.inactiveSideMenu, .activeSideMenu {
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
-webkit-transition: -webkit-transform .4s;
-moz-transition: -moz-transform .4s;
transition: transform .4s;
@include transform(translate3d(0, 0, 0));
}
.activeSideMenu {
@include transform(translate3d(80%, 0, 0));
}
Loading…
Cancel
Save