Top Menu Not Sticky on Page With JS-Generated Content

This is driving me crazy, and I don’t understand why this happens. Try the page at: http://test.stoutbowman.com/blog-index-new.html by loading it, scrolling down a screen-full or two to confirm that the top menu sticks, then reload the page. Now, after a screen-full or two, the sticky menu scrolls up and off the window. If you clear your browser cache and reload the page, the top menu becomes sticky again, until you once again reload it.

The content of the page is generated by javascript retrieving the blog items through an API at Ghost.io. The current page has all the blog items coded in the page HTML and does not exhibit this problem. However, I have the same unstick problem on 6 other pages that generate content from RSS feeds through 6 different API connections, so there must be some unexpected interaction with the browser cache.

On the Sticky doc page, there is this statement for the _calc method: " Called on every scroll event and on _init fires functions based on booleans and cached values". Could this be the problem?

I have tried everything I can think of: executing $(document).foundation() only after the js that fills the page runs, turning off page caching in my .htaccess file for the page, and a whole host of other things. Note that this happens only after the page has been reloaded after the cache is cleared, although I get the same result if I clear cache, load the page, don’t scroll it, and then load it again. If I clear cache, reload the page, navigate to another page using the menu, and then use the browser’s back button to go back to the page, I get the same unsticking.

Any insight into this will be greatly appreciated.

1 Like

Hi, please update the title. What exactly is your question?

Sorry, title updated.

Which exact version of Foundation Sites do you use?

Also a few linebreaks in your question would make it easier to read.

I am using Foundation 6.6.1 CSS, downloaded from
https://unpkg.com/browse/foundation-sites@6.6.1/. Because this site was
originally coded years ago, I am using foundation-6.6.1-float-min.css.

To reproduce the problem:

  1. clear browser cache
  2. go to http://test.stoutbowman.com/blog-index-new.html
  3. confirm that the top menu stays sticky by scrolling down the page
  4. reload the page
  5. now the top menu will scroll off the page, not immediately, but after
    a short scroll
  6. clear browser cache again
  7. confirm that the top menu still scrolls off the page
  8. reload the page again
  9. now the sticky menu stays sticky
  10. reload the page
  11. once again, the top menu will scroll off the page

This is with Chrome 79 Official Build on Ubuntu 16.04, and it fails in
the same way on Firefox 72 on Ubuntu, as well as Chrome 79 on Windows 10.

Can you check if it works with 6.5.3? Because then it is a regression.

No change. The test sequence in my previous post exhibits the exact same
error with foundation-float-6.5.3.css and foundation-6.5.3.min.js - I
coded a new page with the new css and js files at
http://test.stoutbowman.com/blog-index-new-test.html to keep things
separate. One interesting thing is that once I got the new 6.5.3 version
to fail, I edited the browser address bar to point to the previous page
at http://test.stoutbowman.com/blog-index-new.html and without any
refresh (the browser cache had been cleared for my test of 6.5.3), the
6.6.1 version failed as well. It seems that there is something in common
between 6.5.3 and 6.6.1 as far as the loss of the sticky top menu that
is carried over no matter which one is used, or I’m doing the same thing
wrong somewhere else on both tests.

Okay, thanks for the additional information. I will create two codepens based on that and check if this worked in previous releases or not and how we can fix this.

Not sure when I have the time for that. Please remind me if there is no answer next week.

Please wait on further testing - I was able to get it to work with 6.6.1 with one of the js-generated sections (there are two on the page), so it may be something I’m doing wrong rather than a problem with Foundation, in which case I will owe you quite an apology. I’ll keep testing and let you know. Thank you very much for your help.

I really appreciate your help. I’ll be away this weekend and I won’t
even be back until Sunday evening, so don’t hurry.

One other data point: when using Chrome developer tools, the top menu
never becomes unstuck (which of course makes it tough to debug). I think
that dev tools does not use cache at all, so that I am getting a clean
page each time, much like my test scenario where I clear the cache and
load the page. Perhaps something in cache that Foundation uses when
executing _calc is getting overwritten by something else I’m doing or using?

When I added back the second js-generated content, the top menu becomes
unstuck again (after the first clean load). The latest test page is at
http://test.stoutbowman.com/blog-index3.html. BTW, if you load the page
after clearing cache, use the back browser button, and then the forward
button, you get the same failure, so it must have something to do with
the content being injected by the javascript a second time.

There is a BF Cache (back - forward) cache in Chrome which might affect this.

OK, another data point. I slightly changed one of the other pages that generates its content using javascript so that the resulting page was a size similar to the blog-index test page. This page retrieves an RSS feed from CNBC (I increased the number of items from 10 to 20), and uses an AJAX call to get the feed; the blog-index page uses a javascript file from ghost to help implement their API. This page exhibits the exact same failure modes as blog-index.html - reloading the page causes the top menu to unstick, clearing cache and reloading it fixes it until the next reload, and when running the page under Developer Tools it never has a problem.

Can you provide a small reproducible testcase as codepen so we can debug this much easier?

I’d certainly like to do that, but there are a number of problems with that, not the least of which is that I’ve never created a codepen, and would not know how to make the Foundation files available. Then, there’s the issue of the API keys embedded in the javascript that are associated with our account at rss2json dot com. I am not a “web developer” but a financial advisor who codes our firm’s website, so while I have been doing this for years, starting with Foundation 4, this is the only site I’ve worked on.

I guess I’m still focusing on the statement in the docs for the sticky plugin _calc() method: “fires functions based on booleans and cached values” and the fact that normal reloading of the page regenerates the page but does not reload the any of the .js files, while running under Chrome developer tools does not use cache and therefore each reload uses a fresh copy of the js files (my supposition, anyway).

It may be that I just have to live with this, as the only user interaction that would produce this would be if the user goes to one of the js-generated pages, navigates away from it using either a link on the page or the browser forward or back button, then returns to the page in some way, which would regenerate the content but with the cached version of the js file. If they then scrolled down past the point where the menu unsticks, it would scroll off the viewport, but by scrolling down they would get it back.

By the way, a month or so ago I had the same issue when I tried to use Foundationi 6.5 on my Ghost blog theme. The home page used infinitescroll.js, which loaded additional content while the user scrolled down the page. I ultimately solved that by using their newer theme as a base, which had the sticky menu I needed.

Our site has so few users that it has become more of an academic exercise that an actual problem. Unless you can look at the code for _calc and find some reason that regenerating the page size without using a fresh copy of the plugin js I think I’m at an impasse.

Did you already try to fire $(document).foundation() after the content is loaded? This should trigger recalculation and reinitialize components.

I tried it when I was working on the blog-index.html page, and it made no difference, so I didn’t try it on the other pages. Well, I moved the foundation() firing to after the retrieval and insertion of the RSS items and that worked on 5 of the 6 pages – why it doesn’t work on the sixth I have yet to figure out. However, it still does not fix the problem on blog-index.html, so I have re-coded it to use the RSS retrieval instead of the Ghost API retrieval for now, but I’m limited to 15 items that way, so it is not an ideal solution.

The problem seems to be affected by the resulting size of the page, because 4 of the RSS pages never had the top menu come unstuck. One page that did was fixed by moving the firing of foundation() while another still has the problem. I think I’ve reached the point of diminishing returns, but I’ll keep working on it and if I find a final solution I’ll post it here.

Thanks for all your time and help.

I think I’ve found a fix, although it would not necessarily be generalized, but it might help you to figure out what is happening.

When the blog-index.html page was static, it was so long that I added a scroll indicator that stuck to the top of the page just below the top menu. I removed that when I started having the problem with the top menu becoming unstuck, thinking it might be interfering with Foundation’s javascript.

Since everything else I’ve tried has failed, I figured I might as well put it back in and see what happens. Well, when I added it back in, it was stuck to the bottom of the top menu, and when the top menu scrolled off the page, the scroll indicator stayed right where it was and continued to indicate the percentage of vertical scroll. I then looked up the _calc function and added that to the scrollbar.js file that controlled the scroll indicator, and low and behold, the top menu stays stuck! Here’s the scrollbar-js code:

window.onscroll = function() {myFunction()};

function myFunction() {
var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
var height = document.getElementById(‘about’).scrollHeight - document.getElementById(‘footer-section’).scrollHeight;
var scrolled = (winScroll / height) * 100;
document.getElementById(“myBar”).style.width = scrolled + “%”;
$j(’#main-menu’).foundation(’_calc’, true);
}

You can test this at blog-index3.html.

It also works on the 6 RSS-feed pages using js-generated content. These pages do not use the scrollbar javascript, so I added the following to the js file for each:

window.onscroll = function() {foundationCalc()};

function foundationCalc() {
$j(’#main-menu’).foundation(’_calc’, true);
}

Just forcing Foundation to recalc on scroll seems to fix the problem, although I don’t know why a generated-content page has the problem. BTW, I did try setting data-check-every:0 in my data-options for the top menu, but it had no effect on the problem.

Any idea why data-check-every:0 didn’t fix this? I just tested it by removing the scrollbar.js code and adding back data-check-every:0, which according to the doc (“Number of scroll events between the plugin’s recalculating sticky points. Setting it to 0 will cause it to recalc every scroll event, setting it to -1 will prevent recalc on scroll.”) should have done the same thing that I coded manually, but the old unstuck problem returned.

See https://github.com/foundation/foundation-sites/blob/06a8d6a0ab4d7ef164d3422f627d15b5ae22c9b8/js/foundation.sticky.js#L61 and https://github.com/foundation/foundation-sites/blob/06a8d6a0ab4d7ef164d3422f627d15b5ae22c9b8/js/foundation.sticky.js#L129

It is only used for the onscroll eventlistener.
You can trigger that event with $(document).scroll() or $(document.trigger('scroll').

resize can be probably used for sticky too (as it has to recalculate then), see https://github.com/foundation/foundation-sites/blob/06a8d6a0ab4d7ef164d3422f627d15b5ae22c9b8/js/foundation.sticky.js#L143

See https://codepen.io/DanielRuf/pen/XWbWpgy?editors=1111