mirror of https://github.com/twbs/ratchet.git
Browse Source
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
2 changed files with 123 additions and 0 deletions
@ -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)
|
||||||
|
} |
||||||
|
}); |
||||||
|
}()); |
@ -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…
Reference in new issue