如何在 twitter 的 bootstrap 2.1.0中使用新的后缀插件?

关于这个主题的引导文档让我有点困惑。我想实现类似的行为,比如在文档中加上导航栏: 导航栏位于段落/页面标题下方,向下滚动时应该首先滚动到页面的顶部,然后固定在那里进行进一步的滚动。

由于 jsFiddle 不支持导航栏概念,因此我设置了一个单独的页面作为最小的示例: http://i08fs1.ira.uka.de/~s_drr/navbar.html

我用这个作为导航栏:

<div class="navbar affix-top" data-spy="affix" data-offset-top="50">
<div class="navbar-inner">
<div class="container">
<div class="span12">
<a class="brand" href="#">My Brand</a>
This is my navbar.
</div>
</div> <!-- container -->
</div> <!-- navbar-inner -->
</div> <!-- navbar -->

我想我会希望 data-offset-top的值为0(因为酒吧应该“坚持”到非常顶部”,但与50至少有一些效果可观看。

如果还将 javascript 代码放在适当的位置:

     <script>
$(document).ready (function (){
$(".navbar").affix ();
});
</script>

感谢你的帮助。

98134 次浏览

Just implemented this for the first time, and here's what I've found.

The data-offset-top value is the amount of pixels that you must scroll in order for the affixing effect to take place. In your case, once 50px is scrolled, the class on your item is changed from .affix-top to .affix. You'd probably want to set data-offset-top to about 130px in your use case.

Once this class change occurs, you must position your element in css by styling the positioning for class .affix. Bootstrap 2.1 already defines .affix as position: fixed; so all you need to do is add your own position values.

Example:

.affix {
position: fixed;
top: 20px;
left: 0px;
}

To fix this very issue I have modified the affix plugin to emit a jQuery event when an object is affixed or unaffixed.

Here is the pull request: https://github.com/twitter/bootstrap/pull/4712

And the code: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js

And then do this to attach the navbar:

<script type="text/javascript">
$(function(){
$('#navbar').on('affixed', function () {
$('#navbar').addClass('navbar-fixed-top')
});


$('#navbar').on('unaffixed', function () {
$('#navbar').removeClass('navbar-fixed-top')
});
});
</script>

My solution for attach the navbar :

function affixnolag(){


$navbar = $('#navbar');
if($navbar.length < 1)
return false;


h_obj = $navbar.height();


$navbar
.on('affixed', function(){
$navbar.after('<div id="nvfix_tmp" style="height:'+h_obj+'px">');
})
.on('unaffixed', function(){
if($('#nvfix_tmp').length > 0)
$('#nvfix_tmp').remove();
});
}

You need to remove .affix() from your script.

Bootstrap gives the option of accomplishing things either via data-attributes or straight JavaScript most of the time.

You just need to remove the script. Here is my example:

<!DOCTYPE html>
<html>


<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.0/js/bootstrap.min.js"></script>


<style>
#content {
width: 800px;
height: 2000px;
background: #f5f5f5;
margin: 0 auto;
}
.menu {
background: #ccc;
width: 200px;
height: 400px;
float: left;
}
.affix {
position: fixed;
top: 20px;
left: auto;
right: auto;
}
</style>


</head>
<body>
<div id="content">
<div style="height: 200px"></div>


<div class="affix-top" data-spy="affix" data-offset-top="180">
<div class="menu">AFFIX BAR</div>
</div>
</div>
</body>
</html>

I was having a similar problem, and I believe I found an improved solution.

Don't bother specifying data-offset-top in your HTML. Instead, specify it when you call .affix():

$('#nav').affix({
offset: { top: $('#nav').offset().top }
});​

The advantage here is that you can change the layout of your site without needing to update the data-offset-top attribute. Since this uses the actual computed position of the element, it also prevents inconsistencies with browsers that render the element at a slightly different position.


You will still need to clamp the element to the top with CSS. Furthermore, I had to set width: 100% on the nav element since .nav elements with position: fixed misbehave for some reason:

#nav.affix {
position: fixed;
top: 0px;
width: 100%;
}

One last thing: When an affixed element becomes fixed, its element no longer takes up space on the page, resulting in the elements below it to "jump". To prevent this ugliness, I wrap the navbar in a div whose height I set to be equal to the navbar at runtime:

<div id="nav-wrapper">
<div id="nav" class="navbar">
<!-- ... -->
</div>
</div>

.

$('#nav-wrapper').height($("#nav").height());

Here's the obligatory jsFiddle to see it in action.

I've got this from the twitterbootstrap's source code and it's working pretty well:

HTML:

<div class="row">
<div class="span3 bs-docs-sidebar">
<ul id="navbar" class="nav nav-list bs-docs-sidenav">
...
</ul>
</div>
</div>

CSS:

.bs-docs-sidenav {
max-height: 340px;
overflow-y: scroll;
}


.affix {
position: fixed;
top: 50px;
width: 240px;
}

JS:

$(document).ready(function(){
var $window = $(window);
setTimeout(function () {
$('.bs-docs-sidenav').affix({
offset: {
top: function (){
return $window.width() <= 980 ? 290 : 210
}
}
})
}, 100);
});

Thanks to namuol and Dave Kiss for the solution. In my case I had a tiny problem with navbar height and width when I used afflix and collapse plugins together. The problem with width can be easily solved inheriting it from parent element (container in my case). Also I could manage to make it collapsing smoothly with a bit of javascript (coffeescript actually). The trick is to set wrapper height to auto before collapse toggle occurs and fix it back after.

Markup (haml):

#wrapper
#navbar.navbar
.navbar-inner
%a.btn.btn-navbar.btn-collapse
%span.icon-bar
%span.icon-bar
%span.icon-bar


#menu.nav-collapse
-# Menu goes here

CSS:

#wrapper {
width: inherit;
}


#navbar {
&.affix {
top: 0;
width: inherit;
}
}

Coffeescript:

class Navigation
@initialize: ->
@navbar = $('#navbar')
@menu = $('#menu')
@wrapper = $('#wrapper')


@navbar.affix({offset: @navbar.position()})
@adjustWrapperHeight(@navbar.height())


@navbar.find('a.btn-collapse').on 'click', () => @collapse()


@menu.on 'shown', () => @adjustWrapperHeight(@navbar.height())
@menu.on 'hidden', () => @adjustWrapperHeight(@navbar.height())


@collapse: ->
@adjustWrapperHeight("auto")
@menu.collapse('toggle')


@adjustWrapperHeight: (height) ->
@wrapper.css("height", height)


$ ->
Navigation.initialize()

Similar to the accepted answer, you can also do something like the following to do everything in one go:

$('#nav').affix({
offset: { top: $('#nav').offset().top }
}).wrap(function() {
return $('<div></div>', {
height: $(this).outerHeight()
});
});​

This not only invokes the affix plugin, but will also wrap the affixed element in a div which will maintian the original height of the navbar.