【问题标题】:Creating a sticky nav css and jquery创建一个粘性导航 css 和 jquery
【发布时间】:2012-07-17 07:33:11
【问题描述】:

我目前正在为一个网站制作一个粘性导航,我遇到了一些问题,当导航变为position:fixed 时,它似乎跳跃并且看起来“笨拙”,这是我的一个小提琴努力去做,

http://jsfiddle.net/DKtLR/

理想情况下,结果是用户滚动并且导航不在固定位置,直到它滚动出视口,然后变为固定并滑回视图。

【问题讨论】:

  • 在这个例子中如何工作?菜单已经在页面的顶部,没有任何情况下用户的视口在菜单上方。如果菜单不在页面顶部,这可能会更好。
  • 我还要说:如果它已经在页面顶部,请将其留在那里并立即修复它。如果不是,滚动它直到它碰到天花板,然后修复它。
  • 这就是我想要做的,但是当它固定时感觉就像有一个跳跃
  • 你应该看看this one

标签: javascript jquery html css


【解决方案1】:

由于您只希望它在完全超出视口时固定,然后滑入,只需修改 top 属性,然后将其动画化回到视图中。有关工作示例,请参阅 this fiddle

更新

This updated fiddle 应该会更好,因为它只应用尚未应用的行为,并在返回正常的“静态”位置时完全删除动态样式。

请注意,向上滚动时仍有闪烁 - 这是因为导航从其固定位置“跳”回其静态位置。这可以使用与上述动画类似的技术轻松解决。

【讨论】:

  • 当我向下滚动页面时,有没有办法阻止导航闪烁?感谢您的示例,它很棒!
  • 我在 Chrome 中没有看到任何闪烁,您使用的是什么浏览器?
  • mac 上的chrome,在我的本地主机版本的站点上实现时会闪烁。当页面很长并且滚动时间延长时,肯定会闪烁。 jsfiddle.net/D8V7b/2
  • 这是一个与我类似的解决方案,虽然它并没有真正根据菜单高度而是根据一些预定义的尺寸来切换显示。
  • 是的,为了简洁起见,我使用了现有尺寸,但当然您可以很容易地检测到标题高度并改用它。
【解决方案2】:

您可以简单地使用 StickyScroller jquery 插件: http://vertstudios.com/blog/jquery-sticky-scroller-position-fixed-plugin/

【讨论】:

    【解决方案3】:

    在顶部,然后用动画固定,这样它就不会笨重

    This might be the solution你在找因为它在滚动出视图时提供了固定的菜单栏,但是当它从顶部切换到固定时,它会做一个向下滑动的动画,所以感觉不像你描述它笨重

    我在示例中使用的 HTML(简化):

    <div id="menu">
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="#">About</a></li>
            ...
        </ul>
    </div>
    <div id="content" />
    

    CSS当然很简单(只有相关的样式)

    #menu {
        position: absolute;
        width: 100%;
    }
    #menu.out {
        position: fixed;
    }
    #menu ul {
        margin: 0;
        list-style: none;
    }
    #menu ul li {
        display: inline-block;
    }
    

    以及执行它的脚本并且执行得如此之快(因此它执行得尽可能快,因为最慢的部分是调用浏览器原生 getBoundingClientRect() 函数,这意味着它仍然很快,非常快):

    $(function() {
    
        // save element references for faster execution
        var menu = $("#menu");
        var ul = menu.find("ul");
        var content = $("#content")[0];
    
        // get menu actual height
        var menuHeight = menu[0].getBoundingClientRect().bottom;
    
        // detect whether menu is scrolled out
        var inView= true;
    
        $(document).scroll(function(evt) {
            evt.preventDefault();
    
            var top = content.getBoundingClientRect().top;
            var nextInView = (top + menuHeight) > 0;
    
            // did state change so we have to change menu positioning
            if (inView ^ nextInView)
            {
                inView = nextInView;
                if (inView)
                {
                    menu.removeClass("out");
                }
                else
                {
                    menu.addClass("out");
                    ul.hide().slideDown("fast");
                }
            }
        });
    
    });
    

    就是这样。您还可以通过设置顶部样式属性的动画来将动画从 slideDown() 调整为 slide in,同时您确切地知道必须在动画之前放置菜单的视口上方多少像素。

    当您滚动页面并且菜单离开视图时,它会将其切换到固定位置并向下滚动菜单,因此它不仅会跳转到视图中,而且会顺利返回

    【讨论】:

      【解决方案4】:

      我根据this solution 制作了这个替代解决方案。基于setInterval 函数(另见控制台日志)。

      var interval_id = false;
      var curOffset, oldOffset;
      var altmenu;
      $(document).ready(function(){
          altmenu = $('.top-nav')[0].cloneNode(true);
          altmenu.style.position = 'absolute';
          altmenu.style.display = 'none';
          document.body.appendChild(altmenu);
          oldOffset = $(window).scrollTop();
          $(document).bind('scroll',function(){
              if (interval_id) {
                  return;
              }
              //altmenu.style.display = 'none'; // optional
              interval_id = setInterval(function() {
                  curOffset = $(window).scrollTop();
                  if(curOffset == oldOffset) {
                      console.log('scrolling stopped',curOffset);
                      clearInterval(interval_id);
                      interval_id = false;
                      if (curOffset>120) {
                          altmenu.style.display = 'block';
                      } else {
                          altmenu.style.display = 'none';
                      }
                      $(altmenu).css({
                          top: (curOffset-120)+'px'
                      }).animate({
                          top: (curOffset)+'px'
                      }, 500);
                  }
                  oldOffset = curOffset;
              }, 500); //setInterval
          });//scroll
      });//ready
      

      Test scriptjsfiddle 在这里。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多