I have a 100% height div with a nav underneath it and more content under that.
When the user scrolls passed the nav it sticks to the top of the page and when the user goes back to the 100% height div the nav is left behind.
As the div is 100% height the 'data-offset-top' for the nav needs to change dynamically.
The following code works for that:
$('#navigation').affix({
offset: {
top: $('#hero').height()
}
});
However when I resize the page the value of the offset does not get readded to the offset.
The following code checks for the page height to change and then gives the new height to the data-offset-top but it does not ` function affixChange() {
$('#navigation').attr('data-offset-top', $('#hero').height());
$('#navigation').affix({
offset: {
top: $('#hero').height()
}
});
}
affixChange();
setInterval(function(){
affixChange();
console.log($('#hero').height());
}, 1000)
Bootstrap gives you the possibility to pass a function to calculate the offset dynamically:
$('#navigation').affix({
offset: {
top: function() { return $('#hero').height(); }
}
});
Unfortunately if you need data-offset-top
to be set dynamically you need to handle this manually. While domachine
provides the correct answer I wanted to offer here a way to re-calculate the value on page resize and also to add a space holder so that affixing runs smooth e.g. no page jumping when the contents gets affixed. This was an issue for me.
data-offset-top
dynamicallySo I use the following HTML:
<div class="my-affix" data-spy="affix" data-offset-top-dynamic="true" data-content-space-holder="#my-affix-space-holder"></div>
<div id="my-affix-space-holder"></div>
The following CSS:
.my-affix + #my-affix-space-holder {
display: none;
}
.my-affix.affix + #my-affix-space-holder {
display: block;
}
And a JS script:
var $dynamicAffixes = $('[data-offset-top-dynamic]');
$dynamicAffixes.each(function(){
// data-target is used for the element that should be affixed while data-spy is used to have some scroll breakpoint
var $thisAffix = $(this);
var $thisAffixMarginPlaceholder = $($thisAffix.attr('data-content-space-holder'));
var currentAffixHeight = $thisAffix.outerHeight();
// Assign the affix height to content placeholder - to add a margin in the page because of missing content
$thisAffixMarginPlaceholder.css('height', currentAffixHeight);
// Initialize affix height where it should trigger to become sticky
$thisAffix.affix({
offset: {
top: Math.round($(this).offset().top)
}
});
$(window).on('resize', function(){
var isAlreadyAffixed = false;
// Restore affix to its original position if scrolled already so we can calculate properly
if ($thisAffix.hasClass('affix')) {
$thisAffix.removeClass('affix');
isAlreadyAffixed = true;
}
var currentAffixPosition = Math.round($thisAffix.offset().top);
var currentAffixHeight = $thisAffix.outerHeight();
$thisAffix.data('bs.affix').options.offset.top = currentAffixPosition; // a hack
$thisAffixMarginPlaceholder.css('height', currentAffixHeight);
if (isAlreadyAffixed) {
$thisAffix.addClass('affix');
$thisAffix.affix('checkPosition');
}
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With