固定头部 - 滚动时跳动有缺陷

10

我在使用jQuery制作固定头部时遇到了一个具体的问题。我尝试了网络上常用的代码片段,但是发现无论在哪里都会出现同样的错误。

在特定的文档高度(可滚动直至略微超过粘性效果调用),固定头部会在 position: fixedposition: static 之间跳转。

HTML:

<header>
  <div id="not-sticky"></div>
  <div id="sticky"></div>
</header>
<div id="content"> ...


jQuery:

var $sticky = $("#sticky");
var offset = $sticky.offset();
var stickyTop = offset.top;
var windowTop = $(window).scrollTop();
$(window).scroll(function() {
  windowTop = $(window).scrollTop();
  if (windowTop > stickyTop) {
    $sticky.css({
      position: 'fixed',
      top: 0
    });
  }
  else {
    $sticky.css({
      position: '',
      top: ''
    });
  }
});


CSS:

header {
  width: 100%;
}

#not-sticky {
  padding: 50px 0;
  width: 100%;
}

#sticky {
  padding: 24px 0;
  position: relative;
  width: 100%;
  z-index: 25;
}


我还尝试了在#not-sticky上添加与#sticky相同高度的下边距,以保持文档高度不变,但仍然出现了同样的抖动效果。

有什么办法可以解决这个问题吗?

1个回答

13

滚动事件触发次数过多,试图设置一个元素的style将不可避免地创建跳跃(即使几乎无法察觉但仍然不平滑)。

我发现最好的方法是:

  1. 克隆我们的元素,
  2. 让克隆体fixed
  3. 处理克隆体的visibility样式。

纯JS:

;(function(){ /* STICKY */

  var sticky  = document.getElementById("sticky"),
      sticky2 = sticky.cloneNode(true);

  sticky2.style.position = "fixed";
  document.body.appendChild(sticky2);

  function stickIt(){
    sticky2.style.visibility = sticky.getBoundingClientRect().top<0 ? "visible" : "hidden";
  }

  stickIt();
  window.addEventListener("scroll", stickIt, false );
}());
#sticky{
  height:100px;
  background:#ada;
  height:50px;
  position:relative;
  /* needed for clone: */
  top:0; 
  width:100%;
}


/* Just for this demo: */
*{margin:0;padding:0;}
#content{height:2000px; border:3px dashed #444;}
h1{padding:40px; background:#888;}
<h1>Logo</h1>
<div id="sticky">Sticky header</div>
<div id="content">Lorem ipsum...<br>bla bla</div>

当您看到"header"元素的fix属性时,实际上是我们固定的克隆元素显示在最上层。


谢谢,伙计!运行得很好!我希望在不需要包装 DIV 的情况下保持干净的标记,但我会接受它。 - Timo Mämecke
@TimoM 不用谢!我创建了一个可重复使用的函数,所以你可以在DOM readywindow load或者任何需要的地方使用它。你知道,图片加载速度很慢,重新检查滚动值可能会很有用,因为页面有时候可能已经被滚动过了。 - Roko C. Buljan
是的,谢谢你!我已经将jQuery包装到了“DOM ready”中,但这个“sticky()”函数真的很棒! - Timo Mämecke
@Roko C. Buljan,我该如何将粘性元素设置为在页面顶部下方x像素处停留?谢谢! - user742030

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接