¿Cómo usar el nuevo complemento de afijo en el bootstrap 2.1.0 de twitter?

110

La documentación de arranque sobre ese tema es un poco confusa para mí. Quiero lograr un comportamiento similar al de los documentos con la barra de navegación de afijos: la barra de navegación está debajo de un encabezado de párrafo / página, y al desplazarse hacia abajo, primero debe desplazarse hasta llegar a la parte superior de la página, y luego permanecer allí fija para más desplazamientos hacia abajo .

Como jsFiddle no funciona con el concepto de barra de navegación, he configurado una página separada para su uso como un ejemplo mínimo: http://i08fs1.ira.uka.de/~s_drr/navbar.html

Yo uso esto como mi barra de navegación:

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

Creo que me gustaría tener data-offset-topun valor de 0 (ya que la barra debería "pegarse" en la parte superior ", pero con 50 hay al menos algún efecto observable.

Si también coloca el código javascript en su lugar:

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

Cualquier ayuda apreciada.

Dynalon
fuente
¿Está intentando utilizar affix () en la barra de navegación principal de su página?
Nithin Emmanuel
@NithinEmmanuel sí, vea el javascript en la publicación o en la muestra: i08fs1.ira.uka.de/~s_drr/navbar.html
Dynalon
¿Por qué no usa use en .navbar-fixed-toplugar de usar affix ()?
Nithin Emmanuel
6
@NithinEmmanuel porque eso no es lo que quiero. .navbar-fixed-topcolocaría la barra de navegación en la parte superior todo el tiempo . Quiero un encabezado de página ARRIBA de la barra de navegación, y al desplazarse hacia abajo (y por lo tanto, la barra de navegación apostaría a desplazarse), debería quedarse en la parte superior, entonces y solo entonces. Los documentos de Bootstrap utilizaron los mismos mecanismos que un subnav en sus documentos anteriores, lamentablemente lo han eliminado para los documentos 2.1.0.
Dynalon
1
Por un lado, el anidamiento de su Javascript es incorrecto. )};debería ser});
Owen

Respuestas:

160

Tenía un problema similar y creo que encontré una solución mejorada.

No se moleste data-offset-topen especificar en su HTML. En su lugar, especifíquelo cuando llame .affix():

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

La ventaja aquí es que puede cambiar el diseño de su sitio sin necesidad de actualizar el data-offset-topatributo. Dado que esto usa la posición calculada real del elemento, también evita inconsistencias con los navegadores que representan el elemento en una posición ligeramente diferente.


Aún necesitará sujetar el elemento a la parte superior con CSS. Además, tuve que configurar width: 100%el elemento de navegación ya que los .navelementos con position: fixedmal comportamiento por alguna razón:

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

Una última cosa: cuando un elemento fijo se vuelve fijo, su elemento ya no ocupa espacio en la página, lo que hace que los elementos debajo de él "salten". Para evitar esta fealdad, envuelvo la barra de navegación en una divaltura cuya altura configuré para que sea igual a la barra de navegación en tiempo de ejecución:

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

.

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

Aquí está el jsFiddle obligatorio para verlo en acción .

Namuol
fuente
6
Gran consejo para eliminar el "salto": se pasó por alto por completo el hecho de que este elemento se elimina y pensé que mi problema estaba contenido en la parte del afijo / js de mi código.
Thomas
1
¡Esta respuesta es la mejor! Todo funciona como deberia. La parte del "salto" era la que faltaba en la mayoría de los tutoriales que encontré. ¡Gracias!
Ricardo Otero
1
Una corrección importante: use offset () en lugar de position () en su código jquery en su primer fragmento de código. Explicación: La función position () le da el desplazamiento dentro del elemento principal, pero offset () es su posición dentro del documento, que es lo que realmente quiere (sí, los nombres son contraintuitivos). Entonces, su código no funcionaría si su elemento de afijo está dentro de otro elemento. También debe pasar el valor "superior" así: $ ("# nav"). Affix ({offset: {top: $ ('# nav'). Offset (). Top. Y debería estar dentro de un ready () para que sepa que el diseño de la página está completo.
2013
Gracias @orrd - ¡Actualizando mi respuesta y mi violín!
Namuol
¡Agradable! Funciona perfectamente y es muy suave. Por cierto, estoy buscando el mismo ejemplo con un pie de página pegajoso. Si sabe cómo hacerlo, ¿puede actualizar jsFiddle? ¡Gracias!
Jocelyn
76

Acabo de implementar esto por primera vez, y esto es lo que encontré.

El data-offset-topvalor es la cantidad de píxeles que debe desplazarse para que se produzca el efecto de fijación. En su caso, una vez que 50pxse desplaza, la clase de su artículo cambia de .affix-topa .affix. Probablemente desee establecer data-offset-topaproximadamente 130pxen su caso de uso.

Una vez que se produce este cambio de clase, debe colocar su elemento en css diseñando el posicionamiento para la clase .affix. Bootstrap 2.1 ya define .affixcomo position: fixed;así que todo lo que necesita hacer es agregar sus propios valores de posición.

Ejemplo:

.affix {
    position: fixed; 
    top: 20px; 
    left: 0px;
}
Dave Kiss
fuente
1
Thx, de alguna manera funciona. Actualicé mi página de ejemplo a eso. El problema ahora es que, tan pronto como la barra de navegación se "afija" como clase css, la clase css de la barra de navegación se descarta. pero creo que es solo un error / deficiencia de bootstrap. No será fácil de cambiar sin hacerlo en MENOS y reconstruir bootstrap.
Dynalon
Me parece que la .navbarclase se conserva, ¿estás seguro?
Dave Kiss
Gracias por esta respuesta, pasé años tratando de resolver esto
Reuben
Vea mi respuesta para una solución más general ligeramente mejorada.
Namuol
5

Para solucionar este mismo problema, modifiqué el complemento de afijo para emitir un evento jQuery cuando un objeto está adherido o no.

Aquí está la solicitud de extracción: https://github.com/twitter/bootstrap/pull/4712

Y el código: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js

Y luego haz esto para adjuntar la barra de navegación:

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

Debe eliminarlo .affix()de su secuencia de comandos.

Bootstrap ofrece la opción de lograr cosas a través de data-attributesJavaScript o directamente la mayor parte del tiempo.

Patrick Laughlin
fuente
2

Obtuve esto del código fuente de twitterbootstrap y está funcionando bastante 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);
});
Jesús Rodríguez
fuente
1

Solo necesita eliminar el script. Aquí está mi ejemplo:

<!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
fuente
1

Gracias a Namuol y Dave Kiss por la solución. En mi caso, tuve un pequeño problema con la altura y el ancho de la barra de navegación cuando usé afflix y colapsé los complementos juntos. El problema con el ancho se puede resolver fácilmente heredando el elemento principal (contenedor en mi caso). También pude lograr que colapsara sin problemas con un poco de javascript (coffeescript en realidad). El truco consiste en establecer la altura de la envoltura autoantes de que se produzca el cambio de colapso y volver a fijarlo después.

Marcado (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
fuente
0

Mi solución para adjuntar la barra de navegación:

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

De manera similar a la respuesta aceptada, también puede hacer algo como lo siguiente para hacer todo de una vez:

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

Esto no solo invoca el affixcomplemento, sino que también envuelve el elemento adjunto en un div que mantendrá la altura original de la barra de navegación.

Adrian
fuente