Chris Barr
Chris Barr

Reputation: 34022

How do I remove Bootstrap Affix from an element under certain conditions?

I have an element where I'm using the Twitter Bootstrap Affix plugin. If the window gets vertically resized to the point where it is smaller than the height of the item, I'd like to remove the affix functionality from the element since you wouldn't be able to see all of it in the window.

So far I've tried this in the console just to see if it can be removed, but it doesn't seem to be working.

$("#myElement")
  .removeClass("affix affix-top affix-bottom")
  .removeData("affix");

$(window)
  .off("scroll.affix.data-api, click.affix.data-api");

Maybe I'm going about this the wrong way? How Can I programmatically remove the affix from an element that already had it applied?

Upvotes: 13

Views: 19165

Answers (5)

Marcin Skórzewski
Marcin Skórzewski

Reputation: 2854

Deprecated: Answer refers to Twitter Bootstrap v2. Current version is v4.

There are few options to try.

  1. Use function for data-offset-top. Normally, you use the integer value, for number of scrolled pixels to fix the element. According to documentation you can use the JS function, that will calculate the offset dynamically. In this case you can make your function to return different number depending on the conditions of your choice.
  2. Use media query to override affix CSS rule for small window (eg. height 200px or less).

I think, the second variant should be suitable for you. Something like:

@media (max-height: 200px) {
  .affix {
    position: static;
  }
}

If you would provide jsfiddle for your problem others could try to actually solve it, instead of giving just theoretical suggestion, that may or may not work.

PS. Bootstrap's navbar component uses media query for max-width to disable fixed style for small devices. It is good to do that not just because the screen size is to small for navbar, but in mobile devices position: fixed; CSS works really ugly. Take w look at navbar inside the bootstrap-responsive.css file.

Upvotes: 9

Mike Korn
Mike Korn

Reputation: 11

Even though this was answered, I just wanted to give my solution for this in case someone ran into a similar situation as mine.

I modified the offset top option to a ridiculous number that would never get scrolled to. This made it so I did not have to do $(window).off('.affix'); and disable affix for everything.

$('#element-id').data('bs.affix').options.offset.top = 1000000000;

Upvotes: 1

nick
nick

Reputation: 31

On line 1890 of bootstrap is a conditional for whether the default action should be prevented. This allows your to listen for events and if some condition is met, prevent the affix from happening.

line 1890 from bootstrap: if (e.isDefaultPrevented()) return

Example:

$('someselector')
.affix()
.on(
    'affix.bs.affix affix-top.bs.affix affix-bottom.bs.affix'
    , function(evt){  
        if(/* some condition */){  
            evt.preventDefault();  
        }  
    }
);

Upvotes: 3

Chris Barr
Chris Barr

Reputation: 34022

I ended up going for a mostly CSS solution, similar to what @Marcin Skórzewski suggested.

This just adds a new class when the height of the window is shorter than the height of the element.

var sizeTimer;
$(window).on("resize", function() {
    clearTimeout(sizeTimer);
    sizeTimer = setTimeout(function() {
        var isWindowTallEnough = $overviewContainer.height() + 20 < $(window).height();

        if (isWindowTallEnough) {
            $overviewContainer.removeClass("affix-force-top");
        } else {
            $overviewContainer.addClass("affix-force-top");
        }

    }, 300);
});

And then in CSS, this class just gets added:

.affix-force-top{
    position:absolute !important;
    top:auto !important;
    bottom:auto !important;
}

EDIT

For bootstrap 3, this seems to be effective:

$(window).off('.affix');
$("#my-element")
    .removeClass("affix affix-top affix-bottom")
    .removeData("bs.affix");

Upvotes: 18

dcPages
dcPages

Reputation: 106

Your $(window).off is close, according to @fat (author of bootstrap-affix.js) you can disable the plugin like this:

$(window).off('.affix');

That will disable the affix plugin.

See: https://github.com/twitter/bootstrap/issues/5870

Upvotes: 7

Related Questions