Как использовать новый плагин affix в bootstrap 2.1.0 twitter?

110

Документация по начальной загрузке по этой теме меня немного смущает. Я хочу добиться аналогичного поведения, как в документах, с помощью аффиксовой панели навигации: панель навигации находится под заголовком абзаца / страницы, и при прокрутке вниз она должна сначала прокручиваться, пока не достигнет верхней части страницы, а затем закрепить там для дальнейших прокруток .

Поскольку 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>

Любая помощь приветствуется.

Dynalon
источник
вы пытаетесь использовать affix () на главной панели навигации вашей страницы?
Нитин Эммануэль
@NithinEmmanuel да, посмотрите javascript в посте или в образце: i08fs1.ira.uka.de/~s_drr/navbar.html
Dynalon
почему бы вам не использовать use .navbar-fixed-topвместо affix ()?
Нитин Эммануэль,
6
@NithinEmmanuel, потому что я не этого хочу. .navbar-fixed-topпоместит Navbar к вершине все время . Я хочу, чтобы заголовок страницы НАД панелью навигации, и при прокрутке вниз (и, таким образом, панель навигации будет прокручиваться), он должен оставаться наверху - тогда и только тогда. Документы Bootstrap использовали те же механизмы, что и subnav в своих предыдущих документах, но, к сожалению, они удалили его для документов 2.1.0.
Dynalon
1
Во-первых, вложение вашего Javascript неверно. )};должно быть});
Оуэн

Ответы:

160

У меня была аналогичная проблема, и я считаю, что нашел улучшенное решение.

Не беспокойтесь об указании data-offset-topв вашем HTML. Вместо этого укажите его при вызове .affix():

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

Преимущество здесь в том, что вы можете изменить макет своего сайта без необходимости обновлять data-offset-topатрибут. Поскольку при этом используется фактическая вычисленная позиция элемента, это также предотвращает несоответствия с браузерами, которые отображают элемент в немного другой позиции.


Вам все равно нужно будет закрепить элемент сверху с помощью CSS. Кроме того, мне пришлось установить width: 100%элемент nav, поскольку .navэлементы с position: fixedнекорректным поведением по какой-то причине:

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

И последнее: когда прикрепленный элемент фиксируется, его элемент больше не занимает места на странице, в результате чего элементы под ним «прыгают». Чтобы предотвратить это уродство, я оборачиваю панель навигации в элемент div, высоту которого я установил равной высоте панели навигации во время выполнения:

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

.

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

Вот обязательный jsFiddle, чтобы увидеть его в действии .

намуол
источник
6
Отличный совет по удалению «скачка» - полностью упустил из виду тот факт, что этот элемент был удален, и подумал, что моя проблема содержится в части affix / js моего кода.
Thomas
1
Это лучший ответ! Все работает как надо. Часть «прыжок» отсутствовала в большинстве найденных мной руководств. Спасибо!
Рикардо Отеро
1
Одно важное исправление: используйте offset () вместо position () в коде jquery в первом фрагменте кода. Объяснение: Функция position () дает вам смещение в родительском элементе, но offset () - это его позиция в документе, а это именно то, что вам действительно нужно (да, имена противоречат интуиции). Таким образом, ваш код не будет работать, если ваш элемент аффикса находится внутри другого элемента. Вы также должны передавать только "верхнее" значение, например: $ ("# nav"). Affix ({offset: {top: $ ('# nav'). Offset (). Top. И оно должно быть внутри готового (), чтобы вы знали, что макет страницы завершен.
orrd
Спасибо @orrd - Обновление моего ответа и скрипки!
намуол
Ницца! Работает отлично и очень плавно. Кстати, ищу такой же пример с липким нижним колонтитулом. Если вы знаете, как это сделать, можете ли вы обновить jsFiddle? Спасибо!
Jocelyn
76

Только что реализовал это впервые, и вот что я нашел.

data-offset-topЗначение количество пикселей , которое необходимо прокручивать для того , чтобы проставления эффекта иметь место. В вашем случае после 50pxпрокрутки класс вашего элемента меняется с .affix-topна .affix. Вы, вероятно, захотите приступить data-offset-topк 130pxделу в своем варианте использования.

Как только произойдет это изменение класса, вы должны разместить свой элемент в css, задав стиль позиционирования для класса .affix. Bootstrap 2.1 уже определяет , .affixкак position: fixed;так все , что вам нужно сделать , это добавить свои собственные значения позиции.

Пример:

.affix {
    position: fixed; 
    top: 20px; 
    left: 0px;
}
Дэйв Кисс
источник
1
Спасибо, это работает. Я обновил свой пример страницы до этого. Проблема теперь в том, что, как только панель навигации получает «аффикс» как класс css, класс css панели навигации отбрасывается. но я думаю, что это просто ошибка / недостаток начальной загрузки. Нелегко изменить, не сделав это в LESS и не перестроив бутстрап.
Dynalon
Мне кажется, что .navbarкласс сохраняется - вы уверены?
Дэйв Кисс
Спасибо за этот ответ, я потратил целую вечность, пытаясь понять это
Рувим
См. Мой ответ для получения немного улучшенного и более общего решения.
namuol
5

Чтобы исправить эту проблему, я модифицировал плагин affix, чтобы генерировать событие jQuery, когда объект прикреплен или не прикреплен.

Вот запрос на перенос: https://github.com/twitter/bootstrap/pull/4712

И код: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js

А затем сделайте это, чтобы прикрепить навигационную панель:

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

    $('#navbar').on('unaffixed', function () {
        $('#navbar').removeClass('navbar-fixed-top')
    });
});
</script>
Корбин Ю
источник
3

Вам нужно удалить .affix()из вашего скрипта.

Bootstrap в data-attributesбольшинстве случаев дает возможность выполнять задачи либо через JavaScript, либо прямо.

Патрик Лафлин
источник
2

Я получил это из исходного кода twitterbootstrap, и он работает очень хорошо:

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);
});
Хесус Родригес
источник
1

Вам просто нужно удалить скрипт. Вот мой пример:

<!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>
Бекковский
источник
1

Спасибо Намуолу и Дэйву Кисс за решение. В моем случае у меня была небольшая проблема с высотой и шириной навигационной панели, когда я использовал плагины afflix и collapse вместе. Проблема с шириной легко решается унаследовав ее от родительского элемента (в моем случае - контейнера). Также мне удалось заставить его плавно схлопываться с помощью небольшого количества javascript (на самом деле coffeescript). Хитрость заключается в том, чтобы установить высоту обертки до того, autoкак произойдет переключение сворачивания, и исправить ее обратно после.

Разметка (хамл):

#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;
  }
}

Кофейный скрипт:

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
источник
0

Мое решение для прикрепления навигационной панели:

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
источник
0

Как и в принятом ответе, вы также можете сделать что-то вроде следующего, чтобы сделать все за один раз:

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

Это не только вызывает affixплагин, но и оборачивает прикрепленный элемент в div, который поддерживает исходную высоту навигационной панели.

Адриан
источник