Есть 3 блока, 2 из них должны быть фиксированы, но фиксированы они должны быть в тот момент, когда находятся по середине экрана (более подробно на схеме)
Есть главный блок(по центру) и два по бокам, все они выровненный относительно друг друга, нужно что бы при скроле в тот момент, когда 2 блока справа и слева достигали середины они становились фиксированный , а центральный продолжал идти.
Делаю сайт на bootstrap'e 4, там есть готовые классы, например class="sticky-top"
, при использовании которого блок становиться фиксированным когда он находиться в самом верху экрана, до этого он не фиксированный элемент. Нужен такой же функционал, но что бы фиксация была по середине. Проблема такая возникла из за разных размеров экранов. Например если зафиксировать блоки простым position:fixed
на широком экране, то все впринципе будет работать, но на ноутбуках фиксированые блоки не скролятся, и половина контента просто за границами окна
Основной принцип:
Отслеживаем величину верт. прокрутки страницы в слушателе события scroll
.
Проверяем условие верхняя Y-координата блоков
+ половина высоты меньшего из боковых блоков
> половина высоты вьюпорта
:
Если условие выполняется (прокрутка дошла до целевой высоты), то добавляем боковым блокам класс с position: fixed
и top: 50vh
, а также задаем им стиль transform: translate(<величина X-скролла страницы>, -50%)
.
Иначе, если условие не выполняется (то есть, "недокрутили" до нужной нам высоты) - убираем у боковых элементов наш класс, и обнуляем стиль transform
.
Дело в том что position: fixed
делает боковые блоки невосприимчивыми к горизонтальной прокрутке страницы - поэтому, решение на чистом CSS невозможно, и нам необходимо постоянно изменять их translateX
средствами JavaScript.
Пример кода ниже.
Так как фрейм результата маленького размера, нажмите "На всю страницу" и поиграйте с размерами окна браузера.
var $d = document,
$de = $d.documentElement,
leftSb = $d.getElementById('left'),
rightSb = $d.getElementById('right'),
article = $d.getElementById('article');
window.addEventListener('scroll', () => {
let bcr = article.getBoundingClientRect(),
posY = bcr.top + leftSb.offsetHeight / 2,
halfH = $de.clientHeight / 2;
if (posY < halfH) {
leftSb.classList.add('fixed');
rightSb.classList.add('fixed');
leftSb.style.transform = rightSb.style.transform = `translate(${-$de.scrollLeft}px, -50%)`;
} else {
leftSb.classList.remove('fixed');
rightSb.classList.remove('fixed');
leftSb.style.transform = rightSb.style.transform = null;
}
});
#content-top { text-align: center; }
.block-top {
display: inline-block;
width: 300px; height: 200px;
margin: 10px;
background-color: #252;
}
#content-main {
position: relative;
display: flex; flex-wrap: nowrap;
justify-content: space-between;
align-items: flex-start;
min-width: 680px;
border: 1px dashed red;
}
.side-container { flex: 0 0 200px; min-height: 200px; }
.side-block {
width: 200px; height: 200px;
background-color: #a44;
}
#right { height: 300px; }
.side-block.fixed { position: fixed; top: 50vh; }
#article {
flex: 1 0 200px; height: 1500px;
margin: 0 10px; padding: 10px;
background-color: #44a; color: #fff;
font: 30px sans-serif;
}'
<div id="content-top">
<div class="block-top"></div><div class="block-top"></div><div class="block-top"></div><div class="block-top"></div><div class="block-top"></div>
</div>
<div id="content-main">
<div class="side-container">
<div id="left" class="side-block"></div>
</div>
<div id="article" class="">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="side-container">
<div id="right" class="side-block"></div>
</div>
</div>
Пример я делал на мобилке, поэтому не уверен что на компе он будет отображаться как задумано, и прикладываю ссылку на JSbin-демку.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Есть календарь http://joxiru/E2pq88yCBWX6nA даты сделал через слайдер owl carousel, при открытии календаря необходимо чтоб каруселька прокручивалась к нужному...
Добрый деньПри создании сайта возникла проблема, как я полагаю с js bootstrap
Есть секция с проектами и кнопками, как сделать чтоб по нажатию определенной кнопки к ней дбавлялся классactive и скрывались все блоки кроме...
Уважаемые, столкнулся с проблемой, не могу никак её решитьИмеется форма, из неё данные идут на добавление и обновление