最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Bootstrap affix dynamically on resize - Stack Overflow

programmeradmin0浏览0评论

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)
  1. Why is my method not working?
  2. Is there a better way to do this?

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)
  1. Why is my method not working?
  2. Is there a better way to do this?
Share Improve this question edited Feb 27, 2014 at 21:51 madth3 7,34412 gold badges52 silver badges74 bronze badges asked Feb 27, 2014 at 21:04 user3332109user3332109 711 silver badge3 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 19

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.

  • It re-calculates data-offset-top dynamically
  • It sets the offset space dynamically. The space will replace affix when affixed

So 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');
            }
        });
    });

Have you tried monitoring the window for a resize event?

    $(window).resize(function() {
  affixChange();
});
发布评论

评论列表(0)

  1. 暂无评论