这是一款效果很酷又简单实用的 jQuery 和 CSS3 二级下拉菜单特效,该特效在点击触发按钮后,二级下拉菜单会向下滑动覆盖原来的主菜单,关闭后二级下拉菜单又向上滑动回去,二级菜单不占用多余的空间。
这个菜单插件是替代标准的二级下拉菜单的好方法,特别是在你想显示更多的二级子菜单的时候。另外,你可以十分容易的自定义二级下拉菜单的样式,多添加一个搜索框或登录注册表单等等。
HTML结构
该二级下拉菜单的HTML结构有两个主要部分:使用<header>
元素来包裹导航菜单,使用<main>
元素来放置页面的内容。
主导航菜单由两个嵌套的无序列表组成,包裹在一个<nav>
元素中:
< header > < div class = "cd-logo" >< a href = "#0" >< img src = "img/cd-logo.svg" alt = "Logo" ></ a ></ div > < nav class = "cd-main-nav-wrapper" > < ul class = "cd-main-nav" > < li >< a href = "#0" >About</ a ></ li > <!-- other list items here --> < li > < a href = "#0" class = "cd-subnav-trigger" >< span >Categories</ span ></ a > < ul > < li class = "go-back" >< a href = "#0" >Menu</ a ></ li > < li >< a href = "#0" >Category 1</ a ></ li > <!-- other list items here --> </ ul > </ li > </ ul > </ nav > < a href = "#0" class = "cd-nav-trigger" >Menu< span ></ span ></ a > </ header > < main class = "cd-main-content" > <!-- main content here --> </ main > |
CSS样式
在小屏幕设备上,主导航菜单位于屏幕的右侧,默认是隐藏的。当用户点击了导航按钮,<main>
元素和<header>
元素会从右向左滑动出来(为其应用nav-is-visible
class)。
当用户点击.cd-subnav-trigger(一个导航小箭头图标)
按钮,二级菜单会从右向左滑动出来覆盖主菜单。
header.nav-is- visible { transform : translateX ( -260px ); } .cd-main-content.nav-is- visible { transform : translateX ( -260px ); } .cd-main-nav { position : fixed ; top : 0 ; right : 0 ; width : 260px ; visibility : hidden ; } .cd-main-nav.nav-is- visible { visibility : visible ; } .cd-main-nav li ul { position : absolute ; top : 0 ; left : 0 ; width : 100% ; transform : translateX ( 260px ); } .cd-main-nav.moves-out > li > a { /* push the navigation items to the left - and lower down opacity - when secondary nav slides in */ transform : translateX ( -100% ); opacity : 0 ; } .cd-main-nav.moves-out > li > ul { /* reveal secondary nav */ transform : translateX ( 0 ); } |
在桌面设备上(分辨率大于1024px),二级菜单位于header的上部(默认隐藏),当点击导航按钮后会从上往下滑动下来,覆盖主菜单。可以为.cd-logo
(网站logo)和.cd-subnav-trigger
(二级菜单触发按钮)设置一个较高的z-index
,这样可以使它们显示在二级菜单之上。
另外,可以为二级菜单设置和.cd-main-nav
(主菜单)相同的padding
,使它们尺寸相同,还可以在列表的最后插入一个.placeholder
元素来制作和.cd-subnav-trigger
(二级菜单触发按钮)相同的空间大小。
@media only screen and ( min-width : 1024px ) { .cd-main-nav { height : 80px ; /* padding left = logo size + logo left position*/ padding : 0 5% 0 calc( 5% + 124px ); text-align : right ; } .cd-main-nav li ul { height : 80px ; background-color : #7e4d7e ; /* padding left = logo size + logo left position*/ padding : 0 5% 0 calc( 5% + 124px ); transform : translateY ( -80px ); transition : transform 0.3 s 0.2 s; } .cd-main-nav li ul li { opacity : 0 ; transform : translateY ( -20px ); transition : transform 0.3 s 0 s, opacity 0.3 s 0 s; } .cd-main-nav .placeholder { /* never visible or clickable- it is used to take up the same space as the .cd-subnav-trigger */ display : block ; visibility : hidden ; opacity : 0 ; pointer-event: none ; } .cd-main-nav.moves-out > li > ul { transition : transform 0.3 s; transform : translateY ( 0 ); } .cd-main-nav.moves-out > li ul li { opacity : 1 ; transform : translateY ( 0 ); transition : transform 0.3 s 0.2 s, opacity 0.3 s 0.2 s; } } |
JAVASCRIPT
插件中使用jQuery来为元素添加和移除相应的class。
唯一值得注意的事情是在HTML结构中单行菜单要位于<header>
中。在移动设备上,我们希望导航菜单位于屏幕的侧边上,默认隐藏。这里使用jQuery来在移动设备上将导航菜单移出header之外。
jQuery(document).ready( function ($){ //move nav element position according to window width moveNavigation(); $(window).on( 'resize' , function (){ (!window.requestAnimationFrame) ? setTimeout(moveNavigation, 300) : window.requestAnimationFrame(moveNavigation); }); //mobile version - open/close navigation $( '.cd-nav-trigger' ).on( 'click' , function (event){ event.preventDefault(); if ($( 'header' ).hasClass( 'nav-is-visible' )) $( '.moves-out' ).removeClass( 'moves-out' ); $( 'header' ).toggleClass( 'nav-is-visible' ); $( '.cd-main-nav' ).toggleClass( 'nav-is-visible' ); $( '.cd-main-content' ).toggleClass( 'nav-is-visible' ); }); //mobile version - go back to main navigation $( '.go-back' ).on( 'click' , function (event){ event.preventDefault(); $( '.cd-main-nav' ).removeClass( 'moves-out' ); }); //open sub-navigation $( '.cd-subnav-trigger' ).on( 'click' , function (event){ event.preventDefault(); $( '.cd-main-nav' ).toggleClass( 'moves-out' ); }); function moveNavigation(){ var navigation = $( '.cd-main-nav-wrapper' ); var screenSize = checkWindowWidth(); if ( screenSize ) { //desktop screen - insert navigation inside header element navigation.detach(); navigation.insertBefore( '.cd-nav-trigger' ); } else { //mobile screen - insert navigation after .cd-main-content element navigation.detach(); navigation.insertAfter( '.cd-main-content' ); } } function checkWindowWidth() { var mq = window.getComputedStyle(document.querySelector( 'header' ), '::before' ).getPropertyValue( 'content' ).replace(/"/g, '' ); return ( mq == 'mobile' ) ? false : true ; } }); |