waypoint_使用jQuery Waypoint创建粘性导航标题

waypoint

在本教程中,我们将创建一个导航栏,当您向下滚动时,它会陪伴您-我们还将在混合中添加一两个two头以对其进行修饰。


介绍

克里斯·科耶尔(Chris Coyier)在讨论:before:after伪元素的优点时说: “每个人都喜欢丝带。” 我已经看到这些程式化的三角形边缘的丝带在整个互联网上突然冒出(一个著名的例子是Facebook的Introducing Timeline页面),尽管它们具有一定的吸引力,但我不得不承认,它们创造的空间效果并没有。没看对我。

色带之所以受到人们的欢迎是有原因的-色带打破了我们传统上绑定的大多数平面设计范式,并且它们是以不显眼的方式做到这一点的少数视觉元素之一。 但是,正如古老的谚语所说,给猫皮剥皮应该不止一种方式-因此,在本教程中,我将为此类元素提出一种替代的视觉风格,我发现它看起来更自然,更美观。令人愉悦。 希望您喜欢并充分利用它!

我们会做什么

在本教程中,我们将使用HTML5的新元素之一nav标签作为水平链接列表的容器。 我将简要说明如何使用一些CSS使它看起来更漂亮。

最重要的是,您将熟悉jQuery Waypoints插件的基础知识,该插件将提供高级功能:当用户向下滚动时,导航栏将停留在视口的顶部,并进行更改以指示当前部分。 稍微增加一点,我们将使用另一个插件ScrollTo ,以便在用户单击导航链接时提供平滑的滚动和方便的定位。


步骤1:盒子

我确定您已经熟悉HTML5引入的各种新元素 。 在此示例中,我们将使用其中两个: <nav><section> 。 我们将从以下内容开始:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <div class=wrapper>
      <h1>A reasonably large heading.</h1>
      <nav><!-- Navigation. --></nav>
      <section id="section-1">Lorem ipsum ...</section>
      <!-- Type in some longer sections of sample text here. -->
    </div>
    <!-- Scripts will go here. -->
  </body>
</html>

我们将不得不给我们的导航栏一个明确的宽度。 将其宽度设置为比包装纸宽28像素,然后将其向左微移到适当的位置。 我们还使用border-*-radius以及一些任意填充为它的顶部边缘轻轻地倒圆角。

nav {
  position: relative;
  width: 928px;
  padding: 2em;
  margin-left: -14px;
  border-top-left-radius: 14px 7px;
  border-top-right-radius: 14px 7px;
}

接下来,我们将在导航栏中添加一个无序的链接列表,并将其项设置为display: inline-block ,以便将它们全部放在一行上。 我们不需要任何项目符号,因此我们也将使用list-style: none

<nav>
  <ul>
    <li><a class=nav-link href=#section-1>Section 1</a></li>
    <li><a class=nav-link href=#section-2>Section 2</a></li>
    ...some more list items...
  </ul>
</nav>
nav li {
  display: inline-block;
  list-style: none;
}

到目前为止,您应该具有以下内容:


步骤2:边缘

现在,如果只有CSS允许我们拥有多个伪元素(即::after::after ),我们就可以轻松地以语义干净的方式完成导航栏的圆角边缘。 但是我们无法做到这一点,因此我们需要在nav的末尾添加两个非语义div 。 给他们提供类nav-leftnav-right (或者您可以将它们称为富有想象力的类,例如Castor和Pollux )。 它们的宽度为14px,高度为14px,并且距离nav的底端absolute 14px。

如上所示, border-radius属性族可以为每个角取两个值。 这些也可以是元素宽度的百分比,这非常方便-这种方法允许边界半径自动适应框尺寸的变化。

使用::after伪元素创建完成导航栏功能区外观的小“阴影”。 它们的宽度和高度以及边界半径也使用百分比设置。

/* swap ‘left’ with ‘right’ for the other two */

.nav-left {
  position: absolute;
  left: 0;  bottom: -14px;
  width: 14px;  height: 14px;
  background: #848a6a;
  border-bottom-left-radius: 100% 50%;
}

.nav-left::after {
  content: '';
  position: absolute;
  right: 0;
  width: 66%;  height: 66%;
  background: #000;
  border-top-left-radius: 100% 50%;
  border-bottom-left-radius: 100% 50%;
}

我们在这里完成了!

摆脱了大多数不可能的直边丝带的几何形状之后,让我们继续。


步骤3:脚本

为了实现浮动标头效果,我们将使用Caleb Troughton的一个名为Waypoints的jQuery插件。 它的唯一目的是在用户滚动到某个元素时触发事件。 如您所见,它非常简单,但提供了很大的灵活性-您可以在其主页上查看几个示例

在页面中包含jQuery和Waypoint,让我们开始吧!

您首先需要做的是通过在元素上调用.waypoint()方法来注册航点。 当然,这本身不会做任何事情-您必须为事件定义一个处理函数。 最简单的方法是将该函数作为参数传递给.waypoint()

立即尝试:将以下内容添加到脚本中,并滚动到导航栏,弹出消息。

$(function() {                     // When the page has loaded,
  $('nav').waypoint(               // create a waypoint
    function() {
      alert("Waypoint reached.");
    }
  )
});

现在,为了达到我们想要的效果,事情必然会变得更加复杂。 首先,我们需要将导航栏封闭在一个容器中,这将是我们的实际航路点,并用作方便的占位符(在下面进行更多介绍)。

<div class="nav-container">
  <nav>
    ...
  </nav>
</div>

在您CSS中,创建以下CSS规则。 (在此位置,请将nav可能需要的所有垂直边距移动到nav-container

.sticky {
  position: fixed;
  top: 0;
}

我们已经准备好了! 将脚本的内容更改为以下内容:

$(function() {

  // Do our DOM lookups beforehand
  var nav_container = $(".nav-container");
  var nav = $("nav");

  nav_container.waypoint({
    handler: function(event, direction) {
      	nav.toggleClass('sticky', direction=='down');
    }
  });

});

好吧,这一切到底是从哪里来的,您理所当然地问。 好吧,您可能已经发现我们在nav-container附加了一个路标; 只是这次,我们的做法有所不同。 我们没有将处理函数直接传递给.waypoint() ,而是将其封装在一个对象中。 就其本身而言,这没有什么区别:两者都是做同一件事的完全有效的方法。 但是,我们传递的对象可以包含其他几个选项值-因此现在使用它可以使以后的代码更加一致。

我们定义的处理程序函数有两个参数:第一个是标准jQuery event对象,在这里没有什么用。 第二个是特定于Waypoint的:它是一个字符串,其值是'down''up'具体取决于用户到达该Waypoint时以何种方式滚动。

现在,知道用户前进的方向是非常重要的信息,这仅仅是因为它允许我们在任一方向上执行不同的行为。 在处理程序函数的主体中,我们使用的是jQuery的.toggleClass()方法的.toggleClass()变体,该变体提供了一种有用的速记方式:在此语法中,第二个参数确定是否将类添加到目标元素或从中删除。 当用户向下滚动时,表达式direction==='down'计算结果为true ,因此我们的导航栏将接收到sticky类,并停留在视口的顶部。 用户再次向上滚动时,该类将从导航栏中删除,并返回其位置。 立即尝试。

酷吧? 但是,如果您缓慢向下滚动到刚刚创建的航路点,您可能会注意到,由于导航栏从内容流中删除,因此在传递时,内容会“跳跃”一些。 除了看起来很草率之外,这种行为还可能使您的部分内容模糊不清,并损害可用性。 值得庆幸的是,它所要做的只是一个简单的修复-将以下代码添加到您的处理函数中可以使跳转消失。

if (direction == 'down')
  nav_container.css({ 'height':nav.outerHeight() });
else
  nav_container.css({ 'height':'auto' });

这里发生的事情非常明显:如上所述,我们使用nav-container作为占位符。 向下滚动时,我们将扩展其高度,并且下面的内容保持不变。 不过有一个问题-要使其正常工作,您可能希望导航栏周围的任何垂直边距都应应用于nav-container而不是nav

就是这样! 就像许多其他站点一样,我们拥有一个不错的固定导航栏。 节目结束了,伙计们…

…还是? 好吧,您可能仍想看到一两个技巧,而这可能会使您脱颖而出。 如果是这样,请继续阅读。


步骤4:垂直偏移

如果您考虑一下,在很多情况下,当元素到达浏览器视口的最边缘时触发事件并不是您想要的。 幸运的是,Waypoints为此提供了一个方便的选项: offset 。 看起来是这样的:

nav.waypoint( {
  handler: …,
  offset: 50
} )

offset可让您在距元素顶部可变距离的位置创建实际的航路点。 当元素的顶部在视口顶部下方的指定距离处时,正值触发路点;当元素的位置在视口顶部上方远处时,负值触发路径。 )。

offset的值可以是数字(代表固定数量的像素),包含百分比的字符串(解释为视口高度的百分比)或返回多个像素的函数。 最后一个可以提供一些严重的灵活性,稍后我们将使用它。 现在,让我们坚持使用固定值,看看它们有什么用。

首先想到的是在粘性元素上方添加一些空间。 使用offset变量,这很容易:对于距顶部15像素的偏移量,请将offset:15px添加到.waypoint()的选项中,然后在.sticky CSS规则.sticky top:0px更改为top:15px

如果您的设计需要它,则导航栏上方的小坡度也可能是不错的选择。 通过在nav内添加另一个div并编写一些CSS可以轻松实现此目的:

.sticky .nav-above {
  position: absolute;
  top:-15px;
  left:1em;
  right:1em;
  height:15px;
  background: linear-gradient(top, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%);
  /* add cross-browser gradient code as needed */
}

这种相当细微的视觉效果在简约设计中将非常有用。


步骤5:偏移功能

Caleb深思熟虑地将其包含在Waypoint中的一件事是能够动态生成Waypoint的偏移,如下所示:

nav.waypoint( {
  handler: …,
  offset: function() {
    return —(nav.outerHeight()+50);
  }
} )

这使我们有了一个处理程序,该处理程序将在用户已经滚动50px超出元素底部时触发,而无需事先知道其高度。

注意:每次调整窗口大小,添加新的航路点或修改航路点的选项时,都会重新计算此类过程生成的偏移(以及以百分比形式给出的偏移)。 如果您正在做其他可能影响航路点位置的事情(例如更改DOM或页面布局),请确保之后再调用$.waypoints('refresh')以重新计算位置。

在本教程的上下文中,此功能的一种用法是使导航栏从顶部平滑滑动。 请做好准备-以下是迄今为止最大的代码块。 但是,其中应该没有什么您不熟悉的内容,所以可以这样:

var top_spacing = 15;
var waypoint_offset = 50;

nav_container.waypoint({

  handler: function(event, direction) {

    if (direction == 'down') {

      nav_container.css({ 'height' : nav.outerHeight() });
      nav.addClass("sticky")
         .stop()
         .css("top", -nav.outerHeight())
         .animate({"top" : top_spacing});

    } else {

      nav_container.css({ 'height' : 'auto' });
      nav.removeClass("sticky")
         .stop()
         .css("top", nav.outerHeight() + waypoint_offset)
         .animate({"top" : ""});

    }

  },

  offset: function() {
    return &mdash;(nav.outerHeight() + waypoint_offset);
  }

});

不是太寒酸! 所有这些都是标准的jQuery票价:在nav添加或删除sticky类后,我们便会使用.css()覆盖元素的垂直位置,然后使用.animate()其设置为应有的水平。 .stop()通过清除jQuery的事件队列来防止可能的错误。

但是,这样做有一点副作用-由于代码在固定后有效地取代了导航元素的垂直位置,因此您top:15px从CSS中删除top:15px声明。 如果您是一个大项目的一部分,并且由不同的人从事设计和前端脚本编写工作,那么这可能会构成问题,因为很容易丢失此类黑客信息。 只是让您知道,存在一些插件,例如Ariel Flesler出色的jQuery.Rule ,可用于弥合脚本和样式表之间的鸿沟。 您必须自己决定是否需要类似的东西。

当然可以用CSS @keyframes达到类似的效果,但是对它们的支持要少得多(并且有很多供应商前缀),它们的灵活性较差,并且“ up”动画会是一个很大的禁忌。 由于我们没有离开渐进增强的轨道,因此没有理由不坚持使用jQuery的强大功能。


步骤6:突出显示和平滑滚动

随着读者逐步浏览页面的不同部分,您可能需要更改突出显示的项目。 使用Waypoint,这很容易实现。 您需要在脚本中添加以下内容:

$(function() {
  …
  // copy from here…

  var sections = $('section');
  var navigation_links = $('nav a');
 
  sections.waypoint({
    handler: function(event, direction) {
      // handler code
    },
    offset: '35%'
  });

  // …to here
});

这次我们使用的偏移量表示为窗口高度的百分比。 实际上,这意味着将告诉脚本当前正在查看哪个部分的假想线放置在视口顶部的三分之一左右,即观看者在阅读长文本时所处的位置。 一个更强大的解决方案可以使用功能来适应导航栏高度的变化。

但是,我们将在处理程序函数中使用的代码不言自明。 这里是:

var active_section;
      active_section = $(this);
      if (direction === "up") active_section = active_section.prev();

      var active_link = $('nav a[href="#' + active_section.attr("id") + '"]');
      navigation_links.removeClass("selected");
      active_link.addClass("selected");

首先,我们需要知道当前正在查看哪个部分。 如果我们向下滚动,则航路点所属的部分与变为活动状态的部分相同。 但是,向上滚动经过一个航路点就意味着它是前面的部分,因此我们使用.prev()进行选择。 然后,我们将selected类从导航栏中的所有链接中删除,然后将其重新应用到其href属性与当前活动部分的id对应的类。

这工作得很好。 如果您不仅仅想添加和删除类,还可以考虑使用LavaLamp这样的插件。

在某些时候,您可能已经注意到,单击导航栏中的链接会将部分的顶部置于浏览器视口的顶部。 当没有什么东西遮挡屏幕的那部分时,这是违反直觉的。 现在我们有了一个导航栏,这变得非常烦人。 这是Ariel Flesler的ScrollTo进行救援的地方。 将其包括在您的页面中,然后添加以下代码:

navigation_links.click( function(event) {

    $.scrollTo(
      $(this).attr("href"),
      {
        duration: 200,
        offset: { 'left':0, 'top':-0.15*$(window).height() }
      }
    );

  });

(当然,该代码超出了最后一个花括号!)

尽管有更好的方法将函数绑定到click事件,但我们将继续使用最简单的方法: .click().scrollTo()方法的调用方式与.waypoint()非常相似。 它带有两个参数-滚动目标和包含不同选项的对象,在这种情况下,这很容易解释。 单击链接的href属性可以很好地用作滚动目标,并且用作顶部偏移的表达式会将目标放置在视口高度的15%处。


结论

看来我们已经完成了。 我已经向您介绍了便捷的小插件Waypoints,并且我们已经讨论了一些使用案例,这些案例应该使您对可以使用它完成的各种事情有所了解。 我们还实现了更加直观的滚动行为,以实现导航。 向其中添加一些Ajax,您将逐步建立一种无缝的,身临其境的Web体验,这将成为Web的未来……嗯,很可能在短时间内变得流行,然后成为司空见惯,这使网络退伍军人怀念过去的事物。 但是,嘿,事情就是这样。

至于色带,它们最大的缺点是:它们只是一种幻想。 色带的侧面实际上并没有绕过容器的边缘。 它们只会以这种方式出现,当功能区越过从页面边缘伸出的元素时,这将变得非常明显。

由于z-index的工作原理 ,除了首先要避免它之外,似乎没有简单的方法可以解决此冲突。 但是,只要有一些想象力以及jQuery的基本知识,您就可以设计出一种方法,使这些元素在接近它们时脱离功能区 。 但是,这样做远远超出了本教程的范围。 希望我能早晚在这里或在Nettuts +上以快速提示的形式向您显示。 敬请关注!

翻译自: https://webdesign.tutsplus.com/articles/create-a-sticky-navigation-header-using-jquery-waypoints--webdesign-6408

waypoint

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值