When a sticky element has been initialized once, destroyed, and then initialized again, the sticky container does not have a height set.
This is due to the $(window).one('load.zf.sticky', ... only firing once on load of the window. I would expect this would also fail if the sticky plugin is initialized after the page has already fired this event.
See the issue demonstrated here: http://codepen.io/allicarn/pen/mELvEY
A quick and dirty fix:
function loaded() {
if(_this.options.anchor !== ''){
_this.$anchor = $('#' + _this.options.anchor);
}else{
_this._parsePoints();
}
_this._setSizes(function(){
_this._calc(false);
});
_this._events(id.split('-').reverse().join('-'));
}
if (document.readyState == "complete") { loaded(); }
else {
$(window).one('load.zf.sticky', loaded);
}
Another work around, for developers, is to simply call
$(window).trigger('load'); after reinitializing Foundation. It may not be the best way to do it in every case, but it worked for us.
@goyney that's true, but if you have other plugins that are listening for it too, it may have ripple effects.
I am going to try to look into this and address it. Thanks for letting us know.
+1
@Jflem1290 looks like there is a codepen in the original ticket: http://codepen.io/allicarn/pen/mELvEY
I think there is a bug down in the plugin code itself that needs to be addressed, so I don't think we can just work around it with jQuery. I think the pointer to check out the event handler on 'load.zf.sticky' is probably a good one - _init should handle the case where we're already initialized in order to be able to handle reinitialization.
@kball & @acarnwath
I've taken a look at the Sticky plugin and I believe that the window.one is restricting the re-initialization of the plugin once destroyed.
line 1116
before: $(window).one('load.zf.sticky', function () {
after: $(window).trigger('load.zf.sticky', function () {
I've replaced the .one() with .trigger() and it seems to respond as expected. The height of the sticky element regains it height after being destroyed.
I haven't received any errors in the console, yet. I would greatly appreciate any feedback about using this method.
@acarnwath Confirming the only way to successfully get the plugin to work after foundation/sticky plugin has already been initialized is: $(window).trigger('load.zf.sticky'). Attempting to reInit the sticky plugin has no effect and the only way to get it to work was with the aforementioned. Just ran into this in an ember app. Thanks for bugging!
Just had this issue with Foundation 6.3 and could not get it to work with .foundation() or .foundation('_calc', true);. Only way was to call $(window).trigger('load.zf.sticky');.
@wojciech-wieronski in your Ember app, where di dyou call the $(window).trigger('load.zf.sticky'). I've tried it from within the route (scheduling an afterRender), but no luck. When I first display the template, I have to call Ember.$('#elem').foundation() to get the stickys to work, but after I navigate to a different page, then come back to that one, the stickys don't work anymore. I can't seem to figure out how to get them sticky again.
You don't even need to destroy it -- just calling $(document).foundation() after window.onload is enough to trigger the bug. For example, if you change:
<script>
$(document).foundation();
</script>
to
<script>
$(document).ready(function() {
$(document).foundation();
}
</script>
is enough to break it (at least in my browser): https://codepen.io/anon/pen/gxqBzN
My workaround is to call
$(window).trigger('load.zf.sticky');
anytime I call .foundation() after the body is loaded (e.g. after Turbolinks AJAX calls).
The problem is the .one() call here: https://github.com/zurb/foundation-sites/blob/62cc44d6f0677e181d9586967aa37e43d3223ecd/js/foundation.sticky.js#L54
The fix suggested by @acarnwath in https://github.com/zurb/foundation-sites/issues/8394#issue-140263578 seems like the right thing to do.
Are pull requests welcome?
$(window).trigger('load.zf.sticky') works flwalessly in my vuejs app. I do call them in my component mounted and it seems to do the trick. My Application has a sticky header and a sticky left nav, the one trigger I have noticed is called twice. While loading another component, which has a stcky rt navigation, noticed that the one is not triggered and the sticky was not working. Triggering the sticky explicitly on the mounted method, did do the trick....
Also noted the window one method is called only once this time...
`import $ from 'jquery'
import Foundation from 'foundation-sites'
export default {
name: 'foundation-grid-page',
props: [
'reload'
],
data () {
return {
}
},
mounted () {
$(this.$el).foundation()
$(window).trigger('load.zf.sticky')
}
}`
Posting my workaround on here as I spent a long time on this issue today and I'm no further to understanding it.
I'm working on an app within a Rails project using Turbolinks.
@andmej' and @anykeyh's solution here would have worked however because I'm using bottom and top anchors it seems a recalibration was needed.
Hopefully this helps others
document.addEventListener("turbolinks:render", function() {
// Workaround for Foundation Sticky Plugin issues with Turbolinks
// https://github.com/zurb/foundation-sites/issues/8394
$("[data-sticky").on('sticky.zf.unstuckfrom:bottom', function(ev) {
stickyObj = $(ev.currentTarget)
stickyInstance = new Foundation.Sticky(stickyObj)
stickyInstance._parsePoints()
stickyInstance._setSizes()
});
// Timeout required to make sure everything has loaded before triggering event
setTimeout(function(){
$(window).trigger('load.zf.sticky');
}, 2000);
Not sure what the current status of this issue is.
Wouldn't .one => .on fix it?
Most helpful comment
Another work around, for developers, is to simply call
$(window).trigger('load');after reinitializing Foundation. It may not be the best way to do it in every case, but it worked for us.