2016-06-14 3 views
3

Я пытаюсь реализовать аффикс в бутстрапе. Это не должно быть проблемой, но я хочу сделать ее отзывчивой.Bootstrap affix reset not works

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

Я просто ищу его и нашел accepted solution, но, похоже, он не работает.

Это то, что я пробовал:

$(window).off('#myAffix'); 
$('#myAffix').removeData('bs.affix').removeClass('affix affix-top affix-bottom'); 
$('#myAffix').affix({ 
    offset: { 
     top: function() { 
      console.log('Offset top from: ' + $('.navbar').offset().top); 
      return (this.top = $('.navbar').offset().top); 
     } 
    } 
}); 

Я зову его на document.ready, и на window.resize событий.

Я создал для него демоверсию. Это шаги, как вы можете воспроизвести проблему:

  • Когда вы открываете его, изменить размер окна reult пока есть 2 колонки перед окаймленной аффикса, и перезагрузите страницу. Когда вы прокрутите вниз, вы увидите, что аффикс начинает работать, когда ему это нужно.

  • Измените размер окна, пока остается только левая колонка. Affix также работает сейчас.

  • Снова измените размер окна, пока появится правая колонка. Теперь аффикс запустит, когда достигнет предыдущей позиции, высоты левого столбца. Это плохо.

Кажется, мой код работает, но не влияет на аффикс.

PS: Меня не интересует положение аффикса, я просто хочу исправить, когда/где он будет исправлен.

jsFiddle here.

ответ

2

Существует только одно изменение, что нужно сделать для вашего кода, чтобы работать, как вы хотите, и это изменить $(window).off('#myAffix'); к $(window).off('.affix');

Это новая функция:

$.myFunction = function() { 
    $(window).off('.affix') 
    $('#myAffix').removeData('bs.affix').removeClass('affix affix-top affix-bottom'); 
    $('#myAffix').affix({ 
     offset: { 
      top: function() { 
       console.log('Offset top from: ' + $('.navbar').offset().top); 
       return (this.top = $('.navbar').offset().top); 
      } 
     } 
    }); 
}; 
10

В ваш образец, у вас есть в HTML класс .affix-top и атрибут data-spy="affix".

<nav class="navbar scroll-menu affix-top" data-spy="affix" id="myAffix" style="border: 1px solid #f00;"> 
    <ul class="nav navbar-nav" style="font-size: 10px; background: #fff;"> 
    <li><a href="#section1">SECTION ONE</a></li> 
    <li><a href="#section2">SECTION TWO</a></li> 
    </ul> 
</nav> 

Те не требуется, так как .affix-top добавляется динамически плагином при инициализации и атрибут data-spy="affix" также не требуется, так как вы его инициализации с помощью JavaScript.

Итак, ваш HTML будет:

<nav id="myAffix" class="navbar scroll-menu" style="border: 1px solid #f00;"> 
    <ul class="nav navbar-nav" style="font-size: 10px; background: #fff;"> 
    <li><a href="#section1">SECTION ONE</a></li> 
    <li><a href="#section2">SECTION TWO</a></li> 
    </ul> 
</nav> 

Кроме того, в документации указывается следующее:

Используйте аффикс плагин с помощью атрибутов данных вручную или с вашим собственным JavaScript.В обеих ситуациях вы должны предоставить CSS для позиционирования и ширины вашего прикрепленного контента .

Это означает, что вы должны добавить CSS, чтобы установить ширину и положение прикрепленного div.

.affix { 
    top: 40px; 
    /* This is the desired offset where the affixed div will appear */ 
    width: 100%; 
    /* This is the desired width where the affixed div will have */ 
} 

С вышеуказанными изменениями аффикс работает как ожидалось, как на полном экране, так и на маленьком экране.


Но тогда я наткнулся на ошибку! Ошибка появилась при загрузке в полноэкранном режиме, а затем, изменение размера на маленький экран.

На маленьком экране плагин запоминает свойства полноэкранной инициализации offset. Ошибка, что плагин affix связывает обработчик в событии window.scroll, которое никогда не удаляется.

Это ошибка утечки памяти (найдено here), и обходной путь для этого упоминается в ответе.

Таким образом, вместо вызова:

$(window).off('#myAffix'); 

вы должны вызвать следующие для правильного удаления всех событий, созданных предыдущей инициализации

$(window).off('.affix'); 

Чтобы подвести итог, ваши JS будет как:

$.initAffix = function() { 
    $('#myAffix').affix({ 
    offset: { 
     top: function() { 
     console.log('Offset top from: ' + $('.navbar').offset().top); 
     return (this.top = $('.navbar').offset().top); 
     } 
    } 
    }); 
}; 

$.resetAffix = function() { 
    console.log('resetAffix'); 
    $(window).off('.affix'); 
    $('#myAffix').removeData('bs.affix').removeClass('affix affix-top affix-bottom'); 
    $.initAffix(); 
}; 

$(window).on('resize', $.resetAffix); 

$.initAffix(); 

0 Работает demo.

+1

Я должен сказать, что это немного расстраивает, что через 12 часов после того, как я дал свой ответ, вы взяли мой код, немного изменили его, добавили объяснения и написали более длинный ответ, чтобы «выиграть» щедрость. Просто говорю. – Dekel

+0

@Dekel Мой ответ не просто содержит ваш код, он имеет больше шагов, и эти шаги подвели итоги исследования, которое я сделал. Принятый ответ OP упоминает, также содержит ваш ответ, и, как сказал OP, это не сработало. В любом случае, если ОП обнаружит, что ваш ответ решает проблему, он должен принять ваш ответ. –

+0

Ответ на упоминания OP не содержит моего ответа. Проблема заключалась в различиях между '$ (window) .off ('# myAffix');' to '$ (window) .off ('. Affix');'. На этом основано все решение. – Dekel