Подтвердить что ты не робот

Twitter Bootstrap Affix - как придерживаться дна?

Я прочитал документацию, и я чувствую, что делаю именно то, что они показывают в своих примерах. Но когда я пытаюсь, я не могу заставить это работать. Я бы хотел, чтобы он работал так же, как документы. Он становится position:fixed после прокрутки заголовка, а затем, когда он касается нижнего колонтитула, он становится position:absolute и придерживается нижней части.


DEMO: http://jsfiddle.net/uvnGP/1/

JS

$("#account-overview-container").affix({
    offset: {
        top: $("header").outerHeight(true),
        bottom: $("footer").outerHeight(true)
    }
});

SASS

#account-overview-container {
    &.affix{
        top:10px;
        bottom:auto;
    }

    &.affix-top{
        //Do I need this?
    }

    &.affix-bottom{
        position:absolute;
        top:auto;
        bottom:140px;
    }
}
4b9b3361

Ответ 1

Там некоторые изменения из вашего кода, но решение подходит для переменной высоты заголовка и нижнего колонтитула, чувствительной ширины и может быть изменено для фиксированного заголовка.

Вот ссылка

http://jsfiddle.net/uvnGP/131/

Проблема заключалась в том, что когда аффикс попал в нижнюю часть, в ваш контейнер добавился верхний и нижний CSS-стиль (#sidebar), способ исправить для reset стиль нижний для авто, таким образом, только стиль top будет действовать на вашем контейнере

вот код:

var headerHeight = $('header').outerHeight(true); // true value, adds margins to the total height
var footerHeight = $('footer').innerHeight();
$('#account-overview-container').affix({
    offset: {
        top: headerHeight,
        bottom: footerHeight
    }
}).on('affix.bs.affix', function () { // before affix
    $(this).css({
        /*'top': headerHeight,*/    // for fixed height
            'width': $(this).outerWidth()  // variable widths
    });
}).on('affix-bottom.bs.affix', function () { // before affix-bottom
    $(this).css('bottom', 'auto'); // THIS is what makes the jumping
});

Ответ 2

Если вы не возражаете использовать атрибуты "data-" в разметке вместо SASS, это должно работать:

http://www.bootply.com/l95thIfavC

Вы также увидите, что я удалил аффикс JS.

HTML

<div class="well well-small affix-top" data-spy="affix" data-offset-top="150" id="account-overview-container">

CSS

body{
    position:relative;
}
header,
footer{
    background: #ccc;
    padding:40px 0;
    text-align:center;
}
header{
    margin-bottom: 10px;
}

.affix-top {
    top: 155px;
    position:absolute;
}
.affix {
    bottom:140px;
}

Обновление для Bootstrap 3

Чтобы использовать affix-bottom, вам в основном нужно установить высоту нижнего колонтитула или пространства под прикрепленным элементом. Вот пример: http://www.bootply.com/l95thIfavC

Ответ 3

Мне удалось заставить его работать в моем приложении, это вопрос о том, чтобы нижний стиль был согласован с нижней частью, переданной при вызове аффикса. Если нижний колонтитул имеет фиксированную высоту, а ближайший позиционированный родитель - это тело, то это вопрос передачи одного и того же значения для обоих. Это работает достаточно хорошо для документов Bootstrap 2.3, как показано здесь и здесь.

-

Теперь предположим, что у вас нет фиксированного нижнего колонтитула:

Шаг 1: ближайший позиционированный родительский элемент (смещенный родительский элемент)

Прежде всего, мы используем абсолютное позиционирование, чтобы придерживаться его до нижней части, но поскольку ваш ближайший позиционированный родитель будет телом (включая нижний колонтитул), у вас нет фиксированного значения для дна. Чтобы исправить это, мы должны создать новый позиционированный родитель, который охватывает все, кроме нижнего колонтитула (важно: заголовок, вероятно, тоже будет снаружи). Установите position: relative; в верхний .container или один из его предков (важно: нижний колонтитул должен быть после этого элемента).

Шаг 2: Высота нижнего колонтитула

Теперь ваше дно относительно контейнера, а не тела, но нижнее значение аффикса (используемое для того, чтобы знать, когда придерживать аффикс на дне), по-прежнему относится к концу тела, поэтому вам нужно пройти это функция, которая вычисляет высоту элементов после контейнера, если это только нижний колонтитул, тогда этого достаточно: $('footer').outerHeight(true).

Шаг 3: Поиск и устранение неисправностей

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

  • Другие визуальные элементы помимо нижнего колонтитула, которые вы не принимали во внимание, например, вторые нижние колонтитулы или которые не всегда отображаются, например, полезные рельсы -footnotes gem;

  • Расширения браузера, которые присоединяют элементы к DOM, если они скрыты или нет в потоке, тогда вы не должны подсчитывать их высоту, тем легче будет обойти это, чтобы считать только те элементы, которые ваше приложение знает, но затем расширение может привести к нарушению вашего приложения. Вы можете проверить, если это расширение вызывает Вас проблемы с помощью браузера или конфигурации, которые не имеют установленных расширений, или просто перейдя в "режим порно" (Incognito на Chromium (Ctrl + Shift + n), Частный просмотр в Firefox (Ctrl + Shift + p)), если вы не включили расширения на нем.

  • Javascript-библиотеки также добавляют элементы к DOM, вы также не должны подсчитывать их высоту.

Чтобы решить эту проблему, вы можете попробовать, чтобы она работала со всем словом (CoffeeScript с Underscore.js):

_($('footer').nextAll(':visible').addBack())
  .filter((el) -> el.offsetParent?)
  .reduce(((memo, el) -> memo + $(el).outerHeight(true)), 0)

То же самое, с Javascript и jQuery.fn.each:

var sum = 0
$('footer').nextAll(':visible').each(function() {
  this.offsetParent != null && sum += $(this).outerHeight(true)
}
return sum

Или вы могли бы учитывать только те элементы, которые вам известны (я предпочитаю это, а другой - для вызова):

$('footer').outerHeight(true) + ($('#footnotes_debug').outerHeight(true) || 0)

Ответ 4

Короткий ответ: обратите внимание, что содержимое внутри вашего аффикса не использует box-sizing: border-box;, если вы используете границы.

Объяснение: Функция jQuery offset(), используемая в affix.js для вычисления текущей позиции элемента относительно документа, не учитывает границы.

Примечание. jQuery не поддерживает получение смещенных координат скрытых элементов или учет границ, полей или отступов, установленных на элементе body.

Итак, если содержимое внутри вашего аффикса имеет границу, а для параметра box-sizing установлено значение border-box, высота будет включать границу, но смещение не будет, в результате чего вычисление affix будет слегка отключено.

Ответ 5

Решение Пако Ривера работает! Но не так, как он думал. Ват действительно удаляет мерцающую (прыгающую) проблему - это строка:

.on('affix.bs.affix', function () { // before affix
    $(this).css({
        'width': $(this).outerWidth()  // variable widths
    });
})

В целом, вам даже не нужно устанавливать ширину CSS. Просто чтение этого параметра уже помогает. Я упростил код до следующего фрагмента и все еще работает:

.on('affix.bs.affix', function () { // before affix
    $(this).width();
});

Я буду хранить его так, как до следующего выпуска плагина Bootstrap Affix, где я надеюсь, что он исправит его раз и навсегда.

Ответ 6

Ваша скрипка, похоже, работает по желанию, если вы немного увеличите размер окна на скрипке. Учитывая, что веб-сайт будет непригодным для использования в размерах, где аффикс ломается, вы должны либо игнорировать его, либо менять макет для работы с меньшим пространством, а не пытаться исправить проблему. Бутстрап-аффикс в документации не используется для небольших разрешений, и я последую этому примеру.

Ответ 7

Одно из возможных решений - полностью игнорировать ситуацию affix-bottom, установив bottom: null следующим образом:

$("#my-selector").affix({
    offset: {
        top: $("#some-thing").outerHeight(true),
        bottom: null
    }
});

Ответ 8

Просто замените сегмент кода для аффикса в бутстрапе, как показано ниже.

Это идет -

this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() }) 

и это заменяет его

this.$element.offset({ top: scrollHeight - offsetBottom - this.$element.height() })

Приветствия.

Ответ 10

Установите position: absolute для .affix-top и .affix-bottom и position: fixed для .affix.

Согласно официальному doc

Ответ 11

Я сделал эту работу с помощью пробных и ошибок, но это то, что сработало для меня.

JS

$(document).ready(function() {
var SidebarTop = $('#your-affix').offset().top - x; //adjust x to meet your required positioning
    SidebarBottom = $('.site-footer').outerHeight() + x;

    $('#your-affix').affix({
        offset: {
        top: SidebarTop,
        bottom: SidebarBottom
        }
    });
});

CSS

#your-affix.affix {
    top: boo px; //the px from top of the window where you want your sidebar
                 //be when you scroll
    width: foo px; //your sidebar width
  }
#your-affix.affix-bottom {
    position: absolute;
    width: foo px; //your sidebar width
}

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