3

I have a web application that sizes the html and body elements at 100% width and height and puts overflow: scroll on body to create full screen slide elements. I'm using jQuery Waypoints for sticky navigation and to determine which slide is currently visible.

Since the body element is technically the one scrolling, I set context: body. This works as expected in Firefox, but the waypoints won't fire in Chrome or Safari.

I can get the waypoints to fire by manually calling $.waypoints('refresh'); after scrolling to a point where they should have fired, but calling this after every scroll event seems like a very cumbersome solution.

$('body').on('scroll', function(){$.waypoints('refresh');}) —it works, but sure isn't pretty.

I'm assuming this has something to do with how each browser interprets the DOM, but is there a known reason why Chrome and Safari wouldn't play nicely with waypoints in scrollable elements?

I'm looking for one of two things, either what I've done backwards in my use of waypoints, or what the underlying issue is so I can fix it and make waypoints work properly for everyone.

For the record (and before anyone asks), I've done my research and this isn't an issue with fixed elements.

Edit: finally got a CodePen built for this. Take a look.

Community
  • 1
  • 1
justin
  • 1,528
  • 11
  • 26
  • Seems like the issue is with the way you've manipulated `body` and the scrolling behavior. Does setting a timeout on the `scroll` event make it less ugly? that way it wont fire every single scroll but only when the user stops scrolling for certain period, maybe a few milliseconds like when they pick their finger up off the scroller input. – Mike Lyons Nov 06 '13 at 15:32
  • @MikeLyons, I'm currently using the timeout solution and it's more performant, but still feels like a hack that shouldn't be needed. Waypoints is supposed to (and in my experience, does) work with elements when you've manipulated scrolling behavior. That's what the `context: scrollingElement` option is for. It seems as though only Firefox is allowing the waypoints function to access the scroll position of elements within `body`. – justin Nov 06 '13 at 15:54
  • Could you post a link or a [jsfiddle](http://jsfiddle.net/)? – Josh Harrison Nov 06 '13 at 16:41
  • @JoshHarrison I've been trying to build one since I posted this but keep getting called away. I just got it finished and it's at http://codepen.io/justinthrelkeld/pen/qaGlK – justin Nov 06 '13 at 17:09
  • Do you have a codepen for your original implementation? I can't stress enough how much you don't want to use the pen that is posted now on account of how offsets are calculated for fixed elements. – imakewebthings Nov 07 '13 at 17:35
  • @imakewebthings dammit. I did edit the original pen. I saved it when I was testing out Josh's answer below. Rejected the solution, save it anyway. Story of my life. – justin Nov 07 '13 at 17:40
  • **UPDATE** the original pen is back to my original implementation, updated code (seemingly fixed) is [here](http://codepen.io/justinthrelkeld/pen/CDIbJ) – justin Nov 07 '13 at 17:51

4 Answers4

1

Remove overflow:hidden from html. Unfortunately looks like this is required - I hope it doesn't break your layout.

Next, you'll need #nav.stuck { position: fixed; } instead of absolute for a sticky header.

Use this js:

$('#nav').waypoint(function(direction) {
  if (direction == 'down') {
          $(this).addClass('stuck');
        } if (direction == 'up') {
          $(this).removeClass('stuck');
        };
});

That works for me - see http://codepen.io/anon/pen/GgsdH

Josh Harrison
  • 5,927
  • 1
  • 30
  • 44
  • This solves it, but it took me a second to figure out why. Originally when building the layout, we needed to use `context: body` to get it to work at all, but it looks like something had changed and setting `context` was actually causing it to not work Safari and Chrome. Taking `context: body` and `overflow: hidden` out fixed things, but why was `context: body` breaking things to begin with? The `body` element is the one that scrolls, so it would seem it should have worked anyway. – justin Nov 06 '13 at 20:34
  • Also, good catch on the `absolute` vs. `fixed` thing. I typed it into the CodePen wrong... – justin Nov 06 '13 at 20:35
  • Great. If this solved it would you mind accepting the answer? – Josh Harrison Nov 07 '13 at 08:45
  • DO NOT USE the solution where you use the fixed position nav element as the waypoint. You will get a lot of unexpected behavior during any refresh (such as a window resize). – imakewebthings Nov 07 '13 at 17:33
  • I think you misunderstood. This doesn't actually solve the problem. You put me on the right track (still not sure why `context: body` didn't behave as expected...), but like @imakewebthings said, fixed elements should never be used for waypoints, even if they seem to work. – justin Nov 07 '13 at 17:43
1

How about this?

$(window).load(function() {
        $('#myheader').waypoint('sticky');
});

… instead of this:

$(document).ready(function(){   
    $('#myheader').waypoint('sticky');
});

This is of course stupid if you have a huge amount of images to load, but this solution saved my day.

ASz
  • 11
  • 1
0

Try min-height: 100% on body and html instead of height, if appropriate for your layout.

Josh Harrison
  • 5,927
  • 1
  • 30
  • 44
0

Delete overflows and heights in html and body, also context is not needed. Worked for me.

Becario Senior
  • 704
  • 10
  • 18