当前位置: 代码迷 >> Web前端 >> 怎么构建下拉滑动式响应导航菜单
  详细解决方案

怎么构建下拉滑动式响应导航菜单

热度:339   发布时间:2013-09-06 10:17:17.0
如何构建下拉滑动式响应导航菜单

来源:GBin1.com

如何构建下拉滑动式响应导航菜单

 在线演示   在线下载

经过长时间研究移动响应布局,我花了很大功夫研究不同的UI设计。在页面上的主要亮点往往是网站主导航。用户需要快速访问到内容页面,而且这一点是最基本的,无论是在完整的显示器或较小的移动响应屏幕。

在本教程中,我要演示如何结合CSS3 media queries和jQuery管理滑动导航菜单。链接出现在前端,但下降为一个隐藏的菜单,调整后的大小低于600px。同时将出现一个小的下拉菜单,图标会切换打开和关闭命令。

演示及下载源代码

设定文件

顶部区域包含文件的一小部分,我们用来创建效果。我从由谷歌托管的最新jQuery库中复制了常规样式表,所有自定义JS函数被存储在外部文件命名为menu.js。

<!doctype html>
<html lang="en-US">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <title>Responsive Sliding Navigation Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="http://designshack.net/favicon.ico">
  <link rel="icon" href="http://designshack.net/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="styles.css">
  <link rel="stylesheet" type="text/css" media="all" href="http://fonts.googleapis.com/css?family=Boogaloo">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script type="text/javascript" language="javascript" charset="utf-8" src="menu.js"></script>
</head>

大部分页面标记不是很重要,除了标题区域。我试图把一切都设定为固定的高度,但header不能用固定CSS属性,否则控制打开和关闭时页面将不会扩展滑动菜单。所以标题和导航链接在CSS中用line-height设置。 

<header id="topnav">
  <nav>
    <ul>
  <li><a href="#" class="sel">Home</a></li>
  <li><a href="#">About</a></li>
  <li><a href="#">Projects</a></li>
  <li><a href="#">Blog</a></li>
  <li><a href="#">Get in Touch</a></li>
   </ul>
  </nav>
  <a href="#" id="navbtn">Nav Menu</a>        
  <h1><a href="#">Designee</a></h1>
</header><!-- @end #topnav -->

页h1标题最适合最后一个元素,所以header将始终保持恒定高度。标题旁边有一个锚链接 ID #navbtn,包含了滑动菜单链接图标。当宽度低于一定阈值,这个CSS链接才会显示。

在CSS标记位置

通常情况下我不会用到jQuery。切换菜单的唯一问题是,我们无法在CSS中达到效果。jQuery的方法将适用于内联CSS样式,并覆盖默认样式。所以解决方案是使用CSS定位元素,并恰当使用JavaScript完成动画效果。

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
  outline: none;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: none;
  -ms-text-size-adjust: none;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
html { height: 101%; }
body { 
  background: #f8f8f8 url('images/bg.png'); /* BG Neutral http://subtlepatterns.com/ps-neutral/ */
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 62.5%; 
  line-height: 1; 
  color: #343434;
  padding-bottom: 55px;
}
 
::selection { background: #b9e9b9; color: #555; }
::-moz-selection { background: #b9e9b9; color: #555; }
::-webkit-selection { background: #b9e9b9; color: #555; }
 
a { color: #6992c0; }
a:hover { color: #77a4dc; }
 
h2 { font-size: 2.9em; line-height: 1.4em; color: #626262; margin-bottom: 22px; }
 
p { font-size: 1.6em; line-height: 1.7em; color: #777; margin-bottom: 15px; }
 
#w {
  display: block;
  max-width: 900px;
  min-width: 300px;
  margin: 0 auto;
}
 
#content {
  margin: 0 1em;
  background: #fff;
  padding: 0 10px;
}
 
#pagebody {
  padding: 15px 25px;
}

我的默认CSS浏览器重置包括一组自定义代码的页面排版,而且body背景标题是脱离于Subtle模式中立的PS。我不得不把包装 容器和主题容器拆分成2个div,因为要保证页面左右两侧填充,不让页面宽度变为100%。在margin: 0 auto;属性上添加margin值,则会导致失去正中定位。 

/* navigation bar */
#topnav {
  display: block;
  width: 100%;
  position: relative;
}
 
#topnav #navbtn {
  display: none;
  float: right;
  top: 0;
  width: 20px;
  height: 70px;
  background: url('images/menu.png') center no-repeat;
  text-indent: -99999px;
  overflow: hidden;
}
 
#topnav nav {
  position: absolute;
  top: 0; 
  right: -10px;
}
 
#topnav nav ul {
  list-style: none;
}
#topnav nav ul li {
  display: block;
  float: left;
  font-size: 1.4em;
  margin-right: 4px;
}
 
#topnav nav ul li a {
  display: block;
  text-decoration: none;
  line-height: 70px;
  color: #8ea188;
  font-weight: bold;
  padding: 0 10px;
  border-bottom: 2px solid #fff;
 
}
#topnav nav ul li a:hover {
  color: #6f8767;
  background: #ddecd9;
  border-bottom-color: #bdd8b5;
}

通过编辑内部<nav>元素,可以保留对标题栏的控制。通过设置绝对位置我们可以控制导航链接离标题的距离。注意#navbtn是如何保持隐藏的,直到调整大小低于560px,才会显示。除此之外还需设定高度、宽度和定位。

可响应样式

如果浏览器窗口小于560px,我只需做一点小小的改动。560并不是多么神奇的数字,而是默认导航区与logo文本之间恰好比较适合的距离。也是隐藏导航菜单和切换显示图标的临界值。

/* responsive styles */
@media screen and (max-width: 560px) {
  h2 { font-size: 2.2em; }
  p { font-size: 1.45em; line-height: 1.55em; }
  #topnav { height: auto; }
  #topnav nav { 
    display: none; 
    position: static;
    width: 100%;
    top: auto;
    right: auto;
  }
  #topnav nav ul li { float: none; margin: 0; }
  #topnav nav ul li a {
    display: block;
    width: 100%;
    line-height: 1.4em;
    border: 0;
    padding: 6px 9px;
    background: #dcf4dc;
  }
  #topnav nav ul li a:hover {
    background: #cbdcc5;
  }
  #topnav nav ul li a.sel {
    color: #6f8767;
    background: #cbdcc5;
  }
   
  #topnav #navbtn {
    display: block;
  }
}

这也意味着从导航元素除去绝对定位,这样使它呈现为一个静态块。点击屏幕时,导航锚链接会以100%的宽度行呈现以达到最快访问。此外,内部页面headers+paragraphs将被调小,匹配上合适的行高值。

JavaScript互动

menu.js代码最后一点也可以直接包含到HTML文档中。但是由于我们需要处理不只一个切换方法,把标记从动态效果分离出来比较清爽而且高效率。我会把文件分成几段,以便阅读。

$(function(){
  var nb = $('#navbtn');
  var n = $('#topnav nav');
   
  $(window).on('resize', function(){
     
 
    if(nb.is(':hidden') && n.is(':hidden') && $(window).width() > 569) {
      // if the navigation menu and nav button are both hidden,
      // then the responsive nav is closed and the nav menu is still hidden.
      // just display the nav menu which will auto-hide at <560px width and remove class.
      $('#topnav nav').show().addClass('keep-nav-closed');
    }
  }); 

第一大块可以说是最令人困惑的。需要处理微小的错误,来调整浏览器响应与不响应的问题,而不能影响到智能手机。我们把一个事件关联到窗口检查.on() resize。两个不同逻辑语句核对变量目标header nav元件,与之相随的是导航菜单切换链路。

当浏览器可响应状态,用户切换菜单开/关时,将附加内联样式属性。这将超过任何写在样式表中的优先级,而且当菜单打开或者关闭之后也会是个问题。nav有一个永久的显示display: none;甚至当大小被调整到大于560px。

这就是第二个if{}语句检查的目的。当导航和菜单按钮都隐藏,布局响应,用户打开/关闭菜单,然后调整大小恢复到常规视图。所以我们只需要再次显示导航。但有一个问题,jQuery中show()方法也将被附加风格内嵌,意味着调整大小时响应的导航菜单保持永久开放。为了解决这个问题,我添加了一个类.keep-nav-closed.如果关闭导航后调整更大,类就会得到补充。如果保持开放,响应时则一直开放直到调整更大然后再次回落。 

if($(this).width() < 570 && n.hasClass('keep-nav-closed')) {
  // if the nav menu and nav button are both visible,
  // then the responsive nav transitioned from open to non-responsive, then back again.
  // re-hide the nav menu and remove the hidden class
  $('#topnav nav').hide().removeAttr('class');
}

另外一个if{}语句应该有意义,这就是为什么我们要检查这个类。只出现在第二次调整之后,导航打开,然后我们知道当调整回到响应阈 值内它会保持关闭。这是一个奇怪的错误,除了完全移除属性(仍然会导致问题)以外,我还没有找到较微小或更快的解决方案,用于处理内嵌jQuery风格。 所以现在让我们继续来看最后一段JavaScript代码。

$('#topnav nav a,#topnav h1 a,#btmnav nav a').on('click', function(e){
  e.preventDefault(); // stop all hash(#) anchor links from loading
});
 
$('#navbtn').on('click', function(e){
  e.preventDefault();
  $("#topnav nav").slideToggle(350);
});

两个事件处理程序检查点击事件针对不同的目标。首先是锁定到所有不同的锚链接标题导航和页脚节。href值是hash symbols (#)我将它们设置为不加载任何东西。与之类似的是点击导航切换,因为我们不希望加载hash到页面URL。响应隐藏导航菜单将在350毫秒内切换打开和 关闭,完全无视href值。

如何构建下拉滑动式响应导航菜单

via 极客标签

来源:如何构建下拉滑动式响应导航菜单

  相关解决方案