jQuery 魔法线导航

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费额度!

这些“滑动”样式的导航栏已经存在一段时间了,我只是认为最近有机会时可以自己尝试一下。事实证明,这真的非常容易。我为此制作了两个示例。

想法

这个想法是在您将鼠标悬停在导航中的不同链接上时,让某种高亮显示(背景或下划线)跟随您。这将通过 jQuery 及其动画功能来实现。因此,“魔法线”只会通过 JavaScript 追加。添加到列表并设置样式后,当您将鼠标悬停在不同的链接上时,它会计算出左侧位置和宽度并进行动画以匹配。

HTML

这里是一个典型的列表……它具有“group”类,因为它将成为一个水平行,并且需要 clearfix 以使其具有高度。ID 用于 JavaScript 来定位它。

<nav class="nav-wrap">
  <ul class="group" id="example-one">
    <li class="current_page_item"><a href="#">Home</a></li>
    <li><a href="#">Buy Tickets</a></li>
    <li><a href="#">Group Sales</a></li>
    <li><a href="#">Reviews</a></li>
    <li><a href="#">The Show</a></li>
    <li><a href="#">Videos</a></li>
    <li><a href="#">Photos</a></li>
    <li><a href="#">Magic Shop</a></li>
  </ul>
</nav>

请注意围绕它的 .nav-wrap div。这是因为样式的原因,条形会占据屏幕的整个宽度,但导航在其中居中。当我们启动 JavaScript 时,此居中会带来一个问题。

CSS

使用旧的内联列表元素和左浮动锚点使列表水平排列,并避免 阶梯式。魔法线绝对定位在条形下方,这样就不会导致抖动(将鼠标悬停在链接上,动画移到链接上,鼠标现在位于魔法线上而不是链接上,动画返回等)其他所有内容纯粹是样式。

.nav-wrap { margin: 50px auto;  background-color: rgba(0, 0, 0, 0.6); border-top: 2px solid white; border-bottom: 2px solid white; }
#example-one { margin: 0 auto; list-style: none; position: relative; width: 960px; }
#example-one li { display: inline; }
#example-one li a { color: #bbb; font-size: 14px; display: block; float: left; padding: 6px 10px 4px 10px; text-decoration: none; text-transform: uppercase; }
#example-one li a:hover { color: white; }
#magic-line { position: absolute; bottom: -2px; left: 0; width: 100px; height: 2px; background: #fe4902; }

jQuery JavaScript

  1. 当 DOM 准备就绪时……
  2. 设置变量,包括导航的当前左侧偏移量
  3. 在窗口上设置调整大小函数,以在偏移量发生更改时(因为居中)重置该偏移量
  4. 将魔法线追加到导航
  5. 设置当前页面项目的魔法线的位置和宽度
  6. 还将原始宽度和位置设置为数据,以便可以将其用于动画返回
  7. 在悬停时,计算新的宽度和新的左侧位置并对其进行动画
  8. 在悬停回调(鼠标移出)时,动画返回到原始位置

更新,感谢 Daniel 和 Nora Brown 在下面的智能评论。

$(function() {

    var $el, leftPos, newWidth,
        $mainNav = $("#example-one");
    
    $mainNav.append("<li id='magic-line'></li>");
    var $magicLine = $("#magic-line");
    
    $magicLine
        .width($(".current_page_item").width())
        .css("left", $(".current_page_item a").position().left)
        .data("origLeft", $magicLine.position().left)
        .data("origWidth", $magicLine.width());
        
    $("#example-one li a").hover(function() {
        $el = $(this);
        leftPos = $el.position().left;
        newWidth = $el.parent().width();
        $magicLine.stop().animate({
            left: leftPos,
            width: newWidth
        });
    }, function() {
        $magicLine.stop().animate({
            left: $magicLine.data("origLeft"),
            width: $magicLine.data("origWidth")
        });    
    });
});

演示

查看 CodePen 上的示例
jQuery 魔法线
,由 Chris Coyier (@chriscoyier) 创建。
CodePen 上。

问题

Opera 对此很奇怪。它使魔法线的原始宽度成为导航栏的整个宽度,并在悬停时从右侧缩短它。我无法解决这个问题。如果您解决了,太棒了,请告诉我,我将更新本文和演示。

备选版本

查看下面的演示链接,了解使用背景而不是线条并同时对颜色、位置和宽度进行动画的备选版本。基本上是一样的,除了 CSS 略有不同,并且 JavaScript 从 HTML 中的 rel 属性中提取新列表项的颜色。

jQuery 中的颜色动画需要 颜色插件。我刚刚抱怨它不适用于 RGBa 颜色,有人向我发送了一个可以使用的补丁,该补丁包含在下载中。我真的很抱歉,但我记不起他们的名字了!如果那是您,请说出来,我将更新此内容并将补丁归功于您。

归您所有

与往常一样,请随意使用它。最好是在公司项目中使用它并赚取大量的现金。

2011年4月27日更新,以更好地支持 IE 6-10