30

我在这个网站上看到了这个粘性标题:http: //dunked.com/ (不再活动,查看存档站点

当您向下滚动时,粘性标题会从顶部向下移动。

我查看了代码,但它看起来非常复杂。我只明白这一点:正常的标题是用 JS 克隆的,当你向下滚动页面时,它会从顶部开始动画。

4

11 回答 11

62

这是一个开始。基本上,我们在加载时复制标题,然后检查(使用.scrollTop()window.scrollY)查看用户何时滚动超过一个点(例如 200 像素)。然后我们简单地切换一个类(在这种情况下.down),它将原件移动到视图中。

最后,我们需要做的就是将 atransition: top 0.2s ease-in应用于我们的克隆,以便当它处于.down状态时它会滑入视图中。Dunked 做得更好,但稍微玩一下就很容易配置

CSS

header {
  position: relative;
  width: 100%;
  height: 60px;
}

header.clone {
  position: fixed;
  top: -65px;
  left: 0;
  right: 0;
  z-index: 999;
  transition: 0.2s top cubic-bezier(.3,.73,.3,.74);
}

body.down header.clone {
  top: 0;
}

Vanilla JS(根据需要填充

var sticky = {
  sticky_after: 200,
  init: function() {
    this.header = document.getElementsByTagName("header")[0];
    this.clone = this.header.cloneNode(true);
    this.clone.classList.add("clone");
    this.header.insertBefore(this.clone);
    this.scroll();
    this.events();
  },

  scroll: function() {
    if(window.scrollY > this.sticky_after) {
      document.body.classList.add("down");
    }
    else {
      document.body.classList.remove("down");
    }
  },

  events: function() {
    window.addEventListener("scroll", this.scroll.bind(this));
  }
};

document.addEventListener("DOMContentLoaded", sticky.init.bind(sticky));

jQuery

$(document).ready(function() {
  var $header = $("header"),
      $clone = $header.before($header.clone().addClass("clone"));

  $(window).on("scroll", function() {
    var fromTop = $("body").scrollTop();
    $('body').toggleClass("down", (fromTop > 200));
  });
});

较新的思考

虽然以上回答了 OP 的原始问题“Dunked 如何实现这种效果?” ,我不会推荐这种方法。对于初学者来说,复制整个顶部导航可能会非常昂贵,而且我们没有真正的理由不能使用原始导航(需要做一些工作)。

此外,Paul Irish 和其他人写过关于如何制作动画translate()优于使用top. 它不仅性能更高,而且还意味着您不需要知道元素的确切高度。上述解决方案将使用以下内容进行修改(参见 JSFiddle)

header.clone {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  transform: translateY(-100%);
  transition: 0.2s transform cubic-bezier(.3,.73,.3,.74);
}

body.down header.clone {
  transform: translateY(0);
}

使用转换的唯一缺点是,虽然浏览器支持非常好,但您可能希望添加供应商前缀版本以最大限度地提高兼容性。

于 2013-08-22T14:07:16.270 回答
12

这是一个 JS 小提琴http://jsfiddle.net/ke9kW/1/

正如其他人所说,将标题设置为固定,并以 display: none 开头

然后是 jQuery

$(window).scroll(function () {
  if ( $(this).scrollTop() > 200 && !$('header').hasClass('open') ) {
    $('header').addClass('open');
    $('header').slideDown();
   } else if ( $(this).scrollTop() <= 200 ) {
    $('header').removeClass('open');
    $('header').slideUp();
  }
});

其中 200 是您希望它向下移动的高度(以像素为单位)。添加开放类是为了让我们运行一个 elseif 而不是仅仅运行 else,所以一些代码不会不必要地在每个滚动事件上运行,节省一点内存

于 2013-08-22T14:04:57.170 回答
2

这是一个相当多的jQuery 插件列表,可以帮助实现类似的效果:http: //jquery-plugins.net/tag/sticky-scroll

于 2014-08-21T13:18:55.160 回答
1

我使用 jQuery .scroll() 函数使用 scrollTop 跟踪工具栏滚动值的事件。然后我使用条件来确定它是否大于我想要替换的值。在下面的示例中,它是“结果”。如果该值为真,则结果标签添加了一个类“fixedSimilarLabel”,然后将新样式考虑在内。

    $('.toolbar').scroll(function (e) {
//console.info(e.currentTarget.scrollTop);
    if (e.currentTarget.scrollTop >= 130) {
        $('.results-label').addClass('fixedSimilarLabel');
    }
    else {      
        $('.results-label').removeClass('fixedSimilarLabel');
    }
});

http://codepen.io/franklynroth/pen/pjEzeK

于 2015-09-25T16:12:47.077 回答
1

CSS:

header.sticky {
  font-size: 24px;
  line-height: 48px;
  height: 48px;
  background: #efc47D;
  text-align: left;
  padding-left: 20px;
}

JS:

$(window).scroll(function() {
 if ($(this).scrollTop() > 100){  
    $('header').addClass("sticky");
  }
  else{
    $('header').removeClass("sticky");
  }
});
于 2016-03-02T11:20:27.437 回答
1

我建议使用粘性 js,这是我见过的最好的选择。无事可做,只是在你身上添加这个 js

 https://raw.githubusercontent.com/garand/sticky/master/jquery.sticky.js

并使用以下代码:

<script>
  $(document).ready(function(){
    $("#sticker").sticky({topSpacing:0});
  });
</script>

它的 git 仓库:https ://github.com/garand/sticky

于 2017-03-28T10:05:17.253 回答
1

这是一个没有 jQuery only Vanilla JS的简单解决方案。

在示例中,我们只使用“标题”类,您可以将其更改为您想要的任何其他内容。基本上,它会克隆现有的标头,并将其作为固定标头显示在下方。

该解决方案速度很快,因为动画是通过 CSS 过渡完成的,并且没有额外的 JS 动画开销。

您可以调整动画样式以拥有自己的过渡。动画“slidein”用于在向下滚动时显示固定标题,当您希望它在向上滚动到顶部时消失时使用“slideout” 。

(function() {

  //CONFIGURATION
  var headerClassName = 'header'; //Class of your header element
  var stickyAfter = 150; //Show fixed header after this Y offset in px
  
  var header = document.getElementsByClassName(headerClassName)[0];
  var clone = header.cloneNode(true); 
  clone.classList.add('clone'); 
  header.parentElement.appendChild(clone);
  
  var initializeHeader = function() {
    document
    .getElementsByClassName(headerClassName + ' clone')[0]
    .classList.add('initialized');
    return true;
  }
  
  window.onscroll = function() {
    var cl = document.body.classList;
    window.pageYOffset > stickyAfter ? 
      initializeHeader() && cl.add('sticky') : 
      cl.remove('sticky');
  } 

})();
/* GENERAL STYLES */
body {
  min-height: 2000px;
}
.header {
  background: green;
  padding: 7px 20px;
  color: #fff;
  position: relative;
  min-width: 100%;
}

/* STICKY HEADER STYLES */
@keyframes slidein {
  from {
    position: fixed;
    top: -50px;
    opacity: 0;
  }
  to {
    position: fixed;
    top: 0;
    opacity: 1;
  }
}
@keyframes slideout {
  from {
    position: fixed;
    top: 0;
    opacity: 1;
  }
  to {
    position: fixed;
    top: -50px;
    opacity: 0;
  }
}
.header.clone.initialized {
  -webkit-animation: slideout .3s forwards; /* for less modern browsers */
   animation: slideout .3s forwards;
}
body.sticky .header.clone {
  -webkit-animation: slidein .3s forwards; /* for less modern browsers */
   animation: slidein .3s forwards;
}
<div class="header">
  <p>This is demo header</p>
</div>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc mollis augue vel massa dictum gravida. Ut vitae elit ligula. In vitae sagittis lacus. Curabitur vel magna eget mauris vestibulum vestibulum id eget dui. Morbi tempus laoreet gravida. Curabitur vel volutpat lacus. Morbi dictum iaculis nibh. Praesent cursus tempor placerat. Sed posuere dui et diam elementum luctus. Nulla aliquet vestibulum justo.</p>

<p>Integer cursus tellus nec sodales lobortis. Donec dictum pharetra ligula, at lobortis lorem pellentesque non. Nullam volutpat nisi id laoreet condimentum. Morbi vel erat vitae elit sodales iaculis ac ut libero. Cras eget neque at libero feugiat interdum. Praesent eget erat mauris. Maecenas convallis aliquet risus non tempus.</p>

<p>Sed convallis elit a dignissim vestibulum. Quisque pharetra, leo eu eleifend pretium, dolor enim viverra elit, quis aliquet dui lacus sit amet dolor. Quisque sit amet sapien tellus. Nam tristique placerat dui, placerat fringilla magna varius nec. Ut id arcu metus. Aenean eu mollis massa. Vestibulum cursus egestas turpis, a tempor metus mattis eu. Donec fringilla quam non fermentum fringilla.</p>

<p>Nam et lorem leo. Donec libero tortor, laoreet quis maximus at, faucibus fermentum ligula. Curabitur facilisis quam in posuere suscipit. Ut sagittis mauris ullamcorper, feugiat sem sed, egestas lorem. Curabitur ut urna laoreet, commodo dolor id, blandit arcu. Aliquam vitae odio magna. Curabitur eu mi dolor. Praesent tellus lectus, mattis eu nunc ac, sagittis tincidunt nulla.</p>

<p>Morbi augue erat, consectetur non pulvinar et, auctor id mi. Vestibulum a ornare diam, nec dignissim neque. Aliquam sodales orci vitae lorem rhoncus, cursus fermentum nisl hendrerit. Aliquam erat volutpat. Mauris fermentum cursus arcu, in imperdiet lacus ultrices ut. Vivamus ligula nulla, mollis a consequat id, varius sed odio. Proin sed fringilla nunc, at dignissim ipsum. Etiam dictum tortor turpis, ac ornare purus semper non. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec a urna vitae metus vestibulum tincidunt sed gravida metus. Vivamus auctor sed leo eget lacinia. Nulla quis bibendum erat. Nunc dapibus lobortis odio, vel porttitor dui elementum at. Ut neque libero, rutrum vel cursus id, rhoncus vitae felis.</p>

于 2021-07-30T09:36:17.057 回答
0

使用 jquery 的类似解决方案是:

$(window).scroll(function () {
  $('.header').css('position','fixed');
});

这会在滚动时立即将标题变成固定位置的元素

于 2013-08-22T13:59:16.143 回答
0

添加去抖动,以提高效率http://davidwalsh.name/javascript-debounce-function

于 2014-03-19T21:59:25.057 回答
0

这在 Firefox 中对我不起作用。

我们添加了一个基于代码是否将溢出放置在 html 级别的条件。请参阅Animate scrollTop 在 firefox 中不起作用

  var $header = $("#header #menu-wrap-left"),
  $clone = $header.before($header.clone().addClass("clone"));

  $(window).on("scroll", function() {
    var fromTop = Array(); 
    fromTop["body"] = $("body").scrollTop();
    fromTop["html"] = $("body,html").scrollTop();

if (fromTop["body"]) 
    $('body').toggleClass("down", (fromTop["body"] > 650));

if (fromTop["html"]) 
    $('body,html').toggleClass("down", (fromTop["html"] > 650));

  });
于 2016-09-06T20:54:07.033 回答
0

使用 jquery 窗口底部滚动到顶部滚动。

 <script> 

 var lastScroll = 0;

 $(document).ready(function($) {

 $(window).scroll(function(){

 setTimeout(function() { 
    var scroll = $(window).scrollTop();
    if (scroll > lastScroll) {

        $("header").removeClass("menu-sticky");

    } 
    if (scroll == 0) {
    $("header").removeClass("menu-sticky");

    }
    else if (scroll < lastScroll - 5) {


        $("header").addClass("menu-sticky");

    }
    lastScroll = scroll;
    },0);
    });
   });
 </script>
于 2017-07-11T12:25:16.937 回答