Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap 3 affix plugin click bug

TL;DR: Here is a fiddle, click or scroll to see the bug: http://jsfiddle.net/Tetaxa/6cC9w/

I have a page with two columns, on the right is an affixed div (a toolbar) and on the left is some content. This works great when the content is higher than the toolbar. However, when the toolbar is higher, I get some weird behavior. On scroll and click, the toolbar's affixed state toggles and the content collapses.

Here's the relevant html:

<div class="row">
    <div class="col-xs-8">
    <p>Lorem ipsum dolor</p>
    </div>
    <div class="col-xs-4">
        <div class="affixed-div">
            Affixed
        </div>
    </div>
</div>

Here is my javascript. The bottom is calculated to prevent the toolbar from going over the bottom content.

var div = $('.affixed-div');
var row = div.closest('.row');

div.affix({
    offset: {
        bottom: $(document).height() - row.offset().top - row.height(),
        top: div.offset().top
    }
});

And here's the custom css:

.affix {
    top: 0;
}

.affix-bottom {
    position: relative;
}

Am I doing something wrong here? Is it a bug or working as intended? Do I have to manually check the height of the row and only affix the toolbar if the content is higher or is there a better way to avoid it? Should I file a bug report?

like image 686
Tetaxa Avatar asked Oct 31 '13 15:10

Tetaxa


5 Answers

It's maybe a bootstrap bug. The bug exists even now.

The bug is in the Bootstrap plugin Affix.js, Affix.prototype.getState methods

if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false

To fix it. replace to below code.

if (offsetTop != null && this.affixed == 'top') return scrollTop <= offsetTop ? 'top' : false

All this can be my wrong thought

like image 173
장희성 Avatar answered Nov 10 '22 13:11

장희성


The problem only seems to occur when the window is in the top scroll position. As an affix should only make a difference once we're really scrolling I applied the following to my navbar (ID=nav, adapt this to your navbar) to fix the issue:

$( '#nav' ).on( 'affix.bs.affix', function(){
    if( !$( window ).scrollTop() ) return false;
} );

This check if the window is indeed scrolling. I'm loading the bootstrap files off a CDN, so editing the original was not an option.

As noted by @kolunar in his answer affix.bs.affix is fired immediately before the element is affixed, so we can prevent this from happening when we're not scrolling yet by returning false

like image 35
patrick Avatar answered Nov 10 '22 13:11

patrick


I have almost the same bug. Class affix-top is being replaced by the affix class on click. Click again and affix-top reappears. In my case it concerns affix-bottom.

old bug not really resolved yet https://github.com/twbs/bootstrap/issues/4647#issuecomment-8769678

like image 3
vinzentt Avatar answered Nov 10 '22 14:11

vinzentt


I think there is a conditional check to set affix somewhere which toggles the state when the offset is zero. Just change bottom/top offset for one pixel and it will work. In your example I changed bottom offset like this:

bottom: $(document).height() - row.offset().top - row.height() - 1

and it starts working fine. Having said that I am not sure if this is the correct fix. I still have some other problems even after applying this trick. (flicker of the navigator on scroll).

like image 1
Afshin Avatar answered Nov 10 '22 14:11

Afshin


Hope this fix your problem.

    var _toolbar = $('.toolbar');
    var _content = $('.content');
    _toolbar.on('affix.bs.affix', function () {
        if (_toolbar.height() > _content.height()) {
            return false;
        }
    });

Note: affix.bs.affix This event fires immediately before the element has been affixed.

like image 1
Aung Myo Linn Avatar answered Nov 10 '22 13:11

Aung Myo Linn