我正在为我的网站构建基本菜单系统。
演示: http://jsfiddle.net/k46bm0Lb/
当我 a)点击键盘上的ESC时,如何编辑我的代码以关闭菜单? b)点击页面上不是菜单的任何地方。
代码:
/*!
* classie - class helper functions
* from bonzo https://github.com/ded/bonzo
*
* classie.has( elem, 'my-class' ) -> true/false
* classie.add( elem, 'my-new-class' )
* classie.remove( elem, 'my-unwanted-class' )
* classie.toggle( elem, 'my-class' )
*/
/*jshint browser: true, strict: true, undef: true */
/*global define: false */
( function( window ) {
'use strict';
// class helper functions from bonzo https://github.com/ded/bonzo
function classReg( className ) {
return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}
// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var hasClass, addClass, removeClass;
if ( 'classList' in document.documentElement ) {
hasClass = function( elem, c ) {
return elem.classList.contains( c );
};
addClass = function( elem, c ) {
elem.classList.add( c );
};
removeClass = function( elem, c ) {
elem.classList.remove( c );
};
}
else {
hasClass = function( elem, c ) {
return classReg( c ).test( elem.className );
};
addClass = function( elem, c ) {
if ( !hasClass( elem, c ) ) {
elem.className = elem.className + ' ' + c;
}
};
removeClass = function( elem, c ) {
elem.className = elem.className.replace( classReg( c ), ' ' );
};
}
function toggleClass( elem, c ) {
var fn = hasClass( elem, c ) ? removeClass : addClass;
fn( elem, c );
}
var classie = {
// full names
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass,
toggleClass: toggleClass,
// short names
has: hasClass,
add: addClass,
remove: removeClass,
toggle: toggleClass
};
// transport
if ( typeof define === 'function' && define.amd ) {
// AMD
define( classie );
} else {
// browser global
window.classie = classie;
}
})( window );
/**
* main.js
* http://www.codrops.com
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2014, Codrops
* http://www.codrops.com
*/
(function() {
var bodyEl = document.body,
content = document.querySelector( '.content-wrap' ),
openbtn = document.getElementById( 'open-button' ),
closebtn = document.getElementById( 'close-button' ),
isOpen = false;
function init() {
initEvents();
}
function initEvents() {
openbtn.addEventListener( 'click', toggleMenu );
if( closebtn ) {
closebtn.addEventListener( 'click', toggleMenu );
}
// close the menu element if the target it´s not the menu element or one of its descendants..
content.addEventListener( 'click', function(ev) {
var target = ev.target;
if( isOpen && target !== openbtn ) {
toggleMenu();
}
} );
}
function toggleMenu() {
if( isOpen ) {
classie.remove( bodyEl, 'show-menu' );
}
else {
classie.add( bodyEl, 'show-menu' );
}
isOpen = !isOpen;
}
init();
})();
/************Reset**************/
*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;}
html, body { height: 100%; width: 100%; font-family: Helvetica, Arial, sans-serif; }
html, body, div, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, ol, ul, li, form, fieldset, legend, label, table, header, footer, nav, section {
margin: 0;
padding: 0;
border: 0;
}
ol, ul {
list-style: none;
}
header, footer, nav, section, article, hgroup, figure {
display: block;
}
legend {
display: none;
}
/************End Reset**************/
/************Global**************/
body {
font: 100%/1.5 'Gill Sans', 'Droid Sans', 'Calibri', 'Lucida Grande', 'Trebuchet MS', 'Helvetica Neue', 'Arial', sans-serif;
color: #000;
background: #fff;
text-align: left;
}
a {
text-decoration: none;
color: #000;
}
a:hover, a:focus {
color: #000;
}
img {
max-width: 100%;
height: auto;
border: 0;
outline: 0;
}
h1 {
font: normal 14px/1em 'Gill Sans', 'Droid Sans', 'Calibri', 'Lucida Grande', 'Trebuchet MS', 'Helvetica Neue', 'Arial', sans-serif;
text-rendering: optimizeLegibility;
margin-bottom: 0;
text-shadow: 0 2px 0 #fff;
text-transform:lowercase;
}
h2 {
font-size: 1.2em;
font-weight: normal;
margin: 0;
text-rendering: optimizeLegibility;
text-shadow: 0 1px 0 #fff;
}
h3 {
margin: 0;
font-weight: normal;
text-rendering: optimizeLegibility;
text-shadow: 0 1px 0 #fff;
}
p {
margin: 0 0 1em;
}
label {
cursor: pointer;
display: inline-block;
background: #fff;
background: rgba(255,255,255,0.5);
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #333;
-webkit-border-top-right-radius: 0.5em;
-webkit-border-bottom-right-radius: 0.5em;
-webkit-border-top-left-radius: 0.5em;
-webkit-border-bottom-left-radius: 0.5em;
-moz-border-radius-topright: 0.5em;
-moz-border-radius-bottomright: 0.5em;
-moz-border-radius-topleft: 0.5em;
-moz-border-radius-bottomleft: 0.5em;
border-top-right-radius: 0.5em;
border-bottom-right-radius: 0.5em;
border-top-left-radius: 0.5em;
border-bottom-left-radius: 0.5em;
padding: 0.4em 0.5em;
float: left;
width: 50%;
height: 2.4em;
text-transform: uppercase;
}
input,textarea {
display: inline-block;
font-size: 1em;
background: #fff;
background: rgba(255,255,255,0.5);
-webkit-appearance: none;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #333;
border-left: 0;
-webkit-border-radius: 0;
-webkit-border-top-right-radius: 0.5em;
-webkit-border-bottom-right-radius: 0.5em;
-moz-border-radius-topright: 0.5em;
-moz-border-radius-bottomright: 0.5em;
border-top-right-radius: 0.5em;
border-bottom-right-radius: 0.5em;
padding: 0.25em 0.6em;
width: 50%;
float: left;
height: 2.4em;
}
input[type=submit] {
cursor: pointer;
}
select {
font-size: 1em;
background: #fff;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAGCAYAAADOic7aAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTZBOTk1RjMxRjZCMTFFMUFDRjA5NUJCNzg2QTA1OEYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTZBOTk1RjQxRjZCMTFFMUFDRjA5NUJCNzg2QTA1OEYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxNkE5OTVGMTFGNkIxMUUxQUNGMDk1QkI3ODZBMDU4RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxNkE5OTVGMjFGNkIxMUUxQUNGMDk1QkI3ODZBMDU4RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtOZMNcAAABeSURBVHjaYmBgYJgGxP8J4JkMIMb//zgxCDAD8XY8hhwAYjZiDAIBfiC+hMWQh0AsClNEjEEgIA3ET5AM+QbEusgKiDWIAarxM9SgEHRJUgwCAT8grsMmgc8ggAADAGY/m1aWUowGAAAAAElFTkSuQmCC) no-repeat 95% 50% rgba(255,255,255,0.5);
-webkit-appearance: none;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #333;
border-left: 0;
padding: 0.25em 0.6em;
height: 2.4em;
width: 49.5%;
-webkit-border-radius: 0;
-webkit-border-top-right-radius: 0.5em;
-webkit-border-bottom-right-radius: 0.5em;
-webkit-border-top-left-radius: 0.5em;
-webkit-border-bottom-left-radius: 0.5em;
-moz-border-radius-topright: 0.5em;
-moz-border-radius-bottomright: 0.5em;
-moz-border-radius-topleft: 0.5em;
-moz-border-radius-bottomleft: 0.5em;
border-top-right-radius: 0.5em;
border-bottom-right-radius: 0.5em;
border-top-left-radius: 0.5em;
border-bottom-left-radius: 0.5em;
}
select:focus, input:focus {
background-color: #fff;
outline: none;
}
::-webkit-input-placeholder {
color: #999;
}
:-moz-placeholder {
color: #999;
}
/************End Global**************/
/************Custom**************/
footer {
padding:10px;
/*background:#fff;*/
}
header {
position:fixed;
top:0;
right:0;
padding:10px;
}
/* Navigation Menu - Background */
.navigation {
/* critical sizing and position styles */
width: 100%;
height: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
overflow:scroll;
/* non-critical appearance styles */
list-style: none;
background:#fff;
text-transform:lowercase;
font-size:14px;
}
/* Navigation Menu - List items */
.nav-item {
/* non-critical appearance styles */
width: 200px;
padding: 1em;
}
.nav-item a {
/* non-critical appearance styles */
display: block;
padding-bottom:0;
color: #111;
font-size: 1.2em;
text-decoration: none;
}
.nav-item a:hover {
color: #000;
}
.date {
display:block;
}
/* Site Wrapper - Everything that isn't navigation */
.site-wrap {
/* Critical position and size styles */
min-height: 100%;
min-width: 100%;
background-color: white; /* Needs a background or else the nav will show through */
position: relative;
top: 0;
bottom: 100%;
left: 0;
z-index: 1;
/* non-critical apperance styles */
padding: 20px;
}
/* Nav Trigger */
.nav-trigger {
/* critical styles - hide the checkbox input */
position: absolute;
clip: rect(0, 0, 0, 0);
}
label[for="nav-trigger"] {
/* critical positioning styles */
position: fixed;
left: 15px; top: 15px;
z-index: 2;
/* non-critical apperance styles */
height: 30px;
width: 30px;
cursor: pointer;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' x='0px' y='0px' width='30px' height='30px' viewBox='0 0 30 30' enable-background='new 0 0 30 30' xml:space='preserve'><rect width='30' height='6'/><rect y='24' width='30' height='6'/><rect y='12' width='30' height='6'/></svg>");
background-size: contain;
}
/* Make the Magic Happen */
.nav-trigger + label, .site-wrap {
transition: left 0.2s;
}
.nav-trigger:checked + label {
left: 215px;
}
.nav-trigger:checked ~ .site-wrap,.nav-trigger:checked ~ footer {
left: 200px;
}
body {
/* Without this, the body has excess horizontal scroll when the menu is open */
overflow-x: hidden;
}
/* Additional non-critical styles */
h1, h3, p {
max-width: 600px;
/*margin: 0 auto 1em;*/
}
code {
padding: 2px;
background: #ddd;
}
a.request {
font-size: 14px;
padding-top:0;
}
footer p {
font-size:0.7em;
line-height:1.2em;
}
footer i.fa {
font-size:1.3em;
float:left;
margin-right:10px;
}
.menu-wrap a {
color: #b8b7ad;
}
.menu-wrap a:hover,
.menu-wrap a:focus {
color: #c94e50;
}
.content-wrap {
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.content {
position: relative;
background: #b4bad2;
}
.content::before {
position: absolute;
top: 0;
left: 0;
z-index: 10;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.3);
content: '';
opacity: 0;
-webkit-transform: translate3d(100%,0,0);
transform: translate3d(100%,0,0);
-webkit-transition: opacity 0.4s, -webkit-transform 0s 0.4s;
transition: opacity 0.4s, transform 0s 0.4s;
-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
transition-timing-function: cubic-bezier(0.7,0,0.3,1);
}
/* Menu Button */
.menu-button {
position: fixed;
z-index: 1000;
margin: 1em;
padding: 0;
width: 2.5em;
height: 2.25em;
border: none;
text-indent: 2.5em;
font-size: 1.5em;
color: transparent;
background: transparent;
}
.menu-button::before {
position: absolute;
top: 0.5em;
right: 0.5em;
bottom: 0.5em;
left: 0.5em;
background: linear-gradient(#373a47 20%, transparent 20%, transparent 40%, #373a47 40%, #373a47 60%, transparent 60%, transparent 80%, #373a47 80%);
content: '';
}
.menu-button:hover {
opacity: 0.6;
}
/* Close Button */
.close-button {
width: 1em;
height: 1em;
position: absolute;
right: 1em;
top: 1em;
overflow: hidden;
text-indent: 1em;
font-size: 0.75em;
border: none;
background: transparent;
color: transparent;
}
.close-button::before,
.close-button::after {
content: '';
position: absolute;
width: 3px;
height: 100%;
top: 0;
left: 50%;
background: #bdc3c7;
}
.close-button::before {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.close-button::after {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
/* Menu */
.menu-wrap {
position: absolute;
z-index: 1001;
width: 300px;
height: 100%;
background: #373a47;
padding: 2.5em 1.5em 0;
font-size: 1.15em;
-webkit-transform: translate3d(-320px,0,0);
transform: translate3d(-320px,0,0);
-webkit-transition: -webkit-transform 0.4s;
transition: transform 0.4s;
-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
transition-timing-function: cubic-bezier(0.7,0,0.3,1);
}
.menu,
.icon-list {
height: 100%;
}
.icon-list {
-webkit-transform: translate3d(0,100%,0);
transform: translate3d(0,100%,0);
}
.icon-list a {
display: block;
padding: 0.8em;
-webkit-transform: translate3d(0,500px,0);
transform: translate3d(0,500px,0);
}
.icon-list,
.icon-list a {
-webkit-transition: -webkit-transform 0s 0.4s;
transition: transform 0s 0.4s;
-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
transition-timing-function: cubic-bezier(0.7,0,0.3,1);
}
.icon-list a:nth-child(2) {
-webkit-transform: translate3d(0,1000px,0);
transform: translate3d(0,1000px,0);
}
.icon-list a:nth-child(3) {
-webkit-transform: translate3d(0,1500px,0);
transform: translate3d(0,1500px,0);
}
.icon-list a:nth-child(4) {
-webkit-transform: translate3d(0,2000px,0);
transform: translate3d(0,2000px,0);
}
.icon-list a:nth-child(5) {
-webkit-transform: translate3d(0,2500px,0);
transform: translate3d(0,2500px,0);
}
.icon-list a:nth-child(6) {
-webkit-transform: translate3d(0,3000px,0);
transform: translate3d(0,3000px,0);
}
.icon-list a span {
margin-left: 10px;
font-weight: 700;
}
/* Shown menu */
.show-menu .menu-wrap {
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
-webkit-transition: -webkit-transform 0.8s;
transition: transform 0.8s;
-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
transition-timing-function: cubic-bezier(0.7,0,0.3,1);
}
.show-menu .icon-list,
.show-menu .icon-list a {
}
.show-menu .icon-list a {
-webkit-transition-duration: 0.9s;
transition-duration: 0.9s;
}
.show-menu .content::before {
opacity: 1;
-webkit-transition: opacity 0.8s;
transition: opacity 0.8s;
-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
transition-timing-function: cubic-bezier(0.7,0,0.3,1);
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="menu-wrap">
<nav class="menu">
<ul class="navigation">
<li class="nav-item">
<a href="http://localhost:8888/index.php/news/2015/new-entry-test">New Entry Test</a>
</li>
</ul>
</nav>
<i class="close-button fa fa-chevron-left" id="close-button"></i>
</div>
<button class="menu-button" id="open-button">Open Menu</button>
<div class="site-wrap">
<p>hello</p>
</div>
答案 0 :(得分:2)
实施Esc
$(document).keyup(function(e) {
if (e.keyCode == 27) { // Esc keycode
//your code to hide the menu
}
});
隐藏用户点击时(手机):
$('.site-wrap').on('click', function(e){
if($('body').hasClass('show-menu')){
toggleMenu();
}
});
希望它有所帮助!
答案 1 :(得分:1)
$(document).click(function() {
if (isOpen) {
classie.remove(bodyEl, 'show-menu');
isOpen = false;
}
});
$(document).keyup(function(e) {
// ESCAPE key pressed
if (e.keyCode == 27) {
if (isOpen) {
classie.remove(bodyEl, 'show-menu');
isOpen = !isOpen;
}
}
});
答案 2 :(得分:0)
我在我之前的测试项目中使用了“点击其他任何地方关闭”方法,这里有自己的vanilla js画廊:http://my-x-perience.at/?page=shop&device=1&category=3&show=11#detailingamescreenshots
基本上我所做的是,每当你打开一个“模态”框并在该叠加上放置一个eventlistener来关闭你想要的任何内容时,在整个内容上面创建一个叠加(也可以是透明的)。
来源:http://my-x-perience.at/scripts/detailpage.js
摘录:
lightboxBg.addEventListener('click', function(e){
lightbox.style.display = "none";
lightboxBg.style.display = "none";
var left = document.querySelector('#screen-lightbox > div > .fa-arrow-circle-o-left');
var right = document.querySelector('#screen-lightbox > div > .fa-arrow-circle-o-right');
lightboxInnerWrapper.removeChild(left);
lightboxInnerWrapper.removeChild(right);
});