Comment utiliser le nouveau plugin affixe dans le bootstrap 2.1.0 de Twitter?

110

La documentation bootstrap sur ce sujet est un peu déroutante pour moi. Je veux obtenir un comportement similaire comme dans les documents avec l'affixe navbar: la barre de navigation est en dessous d'un en-tête de paragraphe / page, et lors du défilement vers le bas, elle doit d'abord défiler jusqu'à atteindre le haut de la page, puis rester fixe pour d'autres défilements. .

Comme jsFiddle ne fonctionne pas avec le concept de la barre de navigation, j'ai configuré une page distincte à utiliser comme exemple minimal: http://i08fs1.ira.uka.de/~s_drr/navbar.html

J'utilise ceci comme barre de navigation:

<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 -->

Je pense que je voudrais avoir data-offset-topune valeur de 0 (puisque la barre doit "coller" tout en haut "mais avec 50 il y a au moins un effet observable.

Si vous mettez également le code javascript en place:

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

Toute aide appréciée.

Dynalon
la source
essayez-vous d'utiliser affix () sur la barre de navigation principale de votre page?
Nithin Emmanuel
@NithinEmmanuel oui, voir le javascript dans le post ou à l'exemple: i08fs1.ira.uka.de/~s_drr/navbar.html
Dynalon
pourquoi n'utilisez-vous pas use .navbar-fixed-topau lieu d'utiliser affix ()?
Nithin Emmanuel
6
@NithinEmmanuel parce que ce n'est pas ce que je veux. .navbar-fixed-topplacerait la barre de navigation vers le haut tout le temps . Je veux un en-tête de page AU-DESSUS de la barre de navigation, et lors du défilement vers le bas (et donc la barre de navigation parierait défilée), il devrait rester en haut - alors et seulement alors. Les documents Bootstrap utilisaient les mêmes mécanismes qu'un sous-navigateur dans leurs documents précédents, malheureusement ils l'ont supprimé pour les documents 2.1.0.
Dynalon
1
D'une part, l'imbrication de votre Javascript est incorrecte. )};devrait être});
Owen

Réponses:

160

J'avais un problème similaire et je crois avoir trouvé une solution améliorée.

Ne vous embêtez pas à spécifier data-offset-topdans votre HTML. Au lieu de cela, spécifiez-le lorsque vous appelez .affix():

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

L'avantage ici est que vous pouvez modifier la mise en page de votre site sans avoir besoin de mettre à jour l' data-offset-topattribut. Dans la mesure où cela utilise la position réelle calculée de l'élément, cela évite également les incohérences avec les navigateurs qui rendent l'élément à une position légèrement différente.


Vous aurez toujours besoin de serrer l'élément vers le haut avec CSS. De plus, j'ai dû width: 100%activer l'élément nav car les .navéléments se comportent position: fixedmal pour une raison quelconque:

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

Une dernière chose: lorsqu'un élément apposé devient fixe, son élément ne prend plus de place sur la page, ce qui fait que les éléments en dessous "sautent". Pour éviter cette laideur, j'enroule la barre de navigation dans un divdont la hauteur que j'ai définie pour être égale à la barre de navigation à l'exécution:

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

.

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

Voici le jsFiddle obligatoire pour le voir en action .

Namuol
la source
6
Un bon conseil pour supprimer le "saut" - complètement ignoré le fait que cet élément est supprimé et j'ai pensé que mon problème était contenu dans la partie affixe / js de mon code.
Thomas
1
Cette réponse est la meilleure! Tout fonctionne comme il se doit. La partie «saut» était celle qui manquait dans la plupart des didacticiels que j'ai trouvés. Merci!
Ricardo Otero
1
Une correction importante: utilisez offset () au lieu de position () dans votre code jquery dans votre premier extrait de code. Explication: La fonction position () vous donne le décalage dans l'élément parent, mais offset () est sa position dans le document, ce que vous voulez réellement (oui, les noms sont contre-intuitifs). Ainsi, votre code ne fonctionnera pas si votre élément affixe est à l'intérieur d'un autre élément. Vous ne devriez également transmettre que la valeur "top" comme ceci: $ ("# nav"). Affix ({offset: {top: $ ('# nav'). Offset (). Top. Et elle devrait être à l'intérieur d'un ready () pour que vous sachiez que la mise en page est terminée.
Orrd
Merci @orrd - Mise à jour de ma réponse et violon!
namuol
Agréable! Fonctionne parfaitement et c'est très lisse. Au fait, je cherche le même exemple avec un pied de page collant. Si vous savez comment faire cela, pouvez-vous mettre à jour jsFiddle? Merci!
Jocelyn
76

Je viens de l'implémenter pour la première fois, et voici ce que j'ai trouvé.

La data-offset-topvaleur est la quantité de pixels que vous devez faire défiler pour que l'effet d'apposition ait lieu. Dans votre cas, une fois le 50pxdéfilement, la classe de votre élément passe de .affix-topà .affix. Vous voudrez probablement vous mettre data-offset-topà environ130px dans votre cas d'utilisation.

Une fois ce changement de classe effectué, vous devez positionner votre élément en css en stylisant le positionnement de la classe .affix. Bootstrap 2.1 définit déjà .affixcommeposition: fixed; si tout ce que vous avez à faire est d'ajouter vos propres valeurs de position.

Exemple:

.affix {
    position: fixed; 
    top: 20px; 
    left: 0px;
}
Dave Kiss
la source
1
Thx, cela fonctionne un peu. J'ai mis à jour ma page d'exemple pour cela. Le problème est maintenant, dès que la barre de navigation obtient «affixe» en tant que classe css, la classe css navbar est supprimée. mais je pense que c'est juste un bug / shortcomming de bootstrap. Ce ne sera pas facile à changer sans le faire en MOINS et en reconstruisant le bootstrap.
Dynalon
Il me semble que la .navbarclasse est préservée - êtes-vous sûr?
Dave Kiss
Merci pour cette réponse, j'ai passé des siècles à essayer de comprendre cela
Reuben
Voir ma réponse pour une légèrement améliorée et plus générale.
namuol
5

Pour résoudre ce problème, j'ai modifié le plugin affixe pour émettre un événement jQuery lorsqu'un objet est apposé ou non.

Voici la pull request: https://github.com/twitter/bootstrap/pull/4712

Et le code: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js

Et puis faites ceci pour attacher la barre de navigation:

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

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

Vous devez supprimer .affix() de votre script.

Bootstrap donne la possibilité d'accomplir des choses via data-attributesou directement en JavaScript la plupart du temps.

Patrick Laughlin
la source
2

J'ai ceci du code source de twitterbootstrap et cela fonctionne plutôt bien:

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);
});
Jésus Rodriguez
la source
1

Il vous suffit de supprimer le script. Voici mon exemple:

<!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>
Beckovsky
la source
1

Merci à namuol et Dave Kiss pour la solution. Dans mon cas, j'ai eu un petit problème avec la hauteur et la largeur de la barre de navigation lorsque j'ai utilisé les plugins afflix et collapse ensemble. Le problème avec la largeur peut être facilement résolu en héritant de l'élément parent (conteneur dans mon cas). J'ai également pu réussir à le faire s'effondrer en douceur avec un peu de javascript (coffeescript en fait). L'astuce consiste à définir la hauteur de l'enveloppe sur autoavant que la bascule de réduction ne se produise et à la corriger après.

Balisage (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()
Voldy
la source
0

Ma solution pour attacher la barre de navigation:

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();
        });
 }
Florian
la source
0

Similaire à la réponse acceptée, vous pouvez également faire quelque chose comme ce qui suit pour tout faire en une seule fois:

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

Cela n'invoque pas seulement le affixplugin, mais enveloppera également l'élément apposé dans un div qui maintiendra la hauteur d'origine de la barre de navigation.

Adrian
la source