admin管理员组

文章数量:1244437

I have a specific problem on making a sticky header with jQuery. I tried the monly used snippets around the web, but I perceived the same buggy thing everywhere.

At a specific document height (scrollable until a little more than calling of sticky-effect) the sticky header jumps between position: fixed and position: 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;
}


I also tried a margin-bottom on #not-sticky with the same height as the #sticky to keep a constant document-height, but the same jumpy-sticky-effect occurred.

Any idea to fix that thing?

I have a specific problem on making a sticky header with jQuery. I tried the monly used snippets around the web, but I perceived the same buggy thing everywhere.

At a specific document height (scrollable until a little more than calling of sticky-effect) the sticky header jumps between position: fixed and position: 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;
}


I also tried a margin-bottom on #not-sticky with the same height as the #sticky to keep a constant document-height, but the same jumpy-sticky-effect occurred.

Any idea to fix that thing?

Share Improve this question edited Mar 29, 2016 at 6:45 Roko C. Buljan 206k41 gold badges327 silver badges336 bronze badges asked May 13, 2013 at 1:36 Timo MämeckeTimo Mämecke 2872 silver badges14 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 13

Scroll fires too many times and trying to set an element style will always & inevitably create jumps (even barely noticeable but still jaggy).

The best way I've found is to

  1. clone our element,
  2. make that clone fixed
  3. play with clone's visibility style.

Pure 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>

So when you see the "header" fix, that's actually our fixed clone getting visible on-top.

本文标签: javascriptSticky Headerbuggy jumping on scrollStack Overflow