Ответ 1
Причина, по которой это происходит, заключается в том, что как только вы дадите position: fixed
вашему элементу #sticky
, он вытащит его из потока документов. Это означает, что все ваши элементы div.child
смещаются вверх, что увеличивает высоту вашего элемента контейнера. Поскольку высота контейнерного элемента становится меньше, элемент контейнера больше не нужно прокручивать, что означает, что его полоса прокрутки исчезает, а ее положение прокрутки reset до 0. Когда ее положение прокрутки reset равно 0, script снова удаляет класс stick
из вашего элемента #sticky
, и мы вернулись туда, где мы начали, но с элементом контейнера, прокручиваемым вплоть до вершины.
Вкратце:
-
#sticky
элемент получает.stick
класс. -
#sticky
элемент удаляется из потока документов, дочерние элементы сдвигаются, высота элемента контейнера уменьшается, а полоса прокрутки исчезает. КонтейнерscrollTop
равен reset до 0. -
Script снова запускается, удаляя класс
.stick
из#sticky
, а контейнерscrollTop
остается равным 0 (таким образом, контейнер div прокручивается обратно вверх).
Ниже приведено решение, которое использует position: absolute
для элемента #sticky
, и когда элемент #sticky
получает класс stick
, он дает элементу #sticky-anchor
высоту, равную высоте #sticky
, чтобы предотвратить перемещение дочерних divs вверх.
Рабочая демонстрация в реальном времени:
function sticky_relocate() {
var window_top = $('#container').scrollTop();
var div_top = $('#sticky-anchor').offset().top;
$('.stick').css('width', $('#sticky').next().css('width'));
if (window_top > div_top) {
$('#sticky-anchor').height($("#sticky").outerHeight());
$('#sticky').addClass('stick');
$("#sticky").css("top", (window_top) + "px");
} else {
$('#sticky').removeClass('stick');
$('#sticky-anchor').height(0);
}
}
$(function () {
$('#container').scroll(sticky_relocate);
sticky_relocate();
});
.child {
height: 200px;
background: gray;
}
#sticky {
padding: 0.5ex;
background-color: #333;
color: #fff;
font-size: 2em;
border-radius: 0.5ex;
}
#sticky.stick {
position: absolute;
top: 0;
z-index: 10000;
border-radius: 0 0 0.5em 0.5em;
}
body {
margin: 1em;
}
p {
margin: 1em auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br>
<br>
<br>
<div id="container" style="overflow-y: auto; height: 800px; position: relative;">
<div id="sticky-anchor"></div>
<div id="sticky">This will stay at top of page</div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>