Пример реализации: https://codepen.io/mmbotelho/pen/NLRLYN
т.е. когда меняется информация (заголовок, текст, изображение) в статичной области при скроллинге. Предположим что такой блок нужен на лэндинге, причем располагается не на первом экране, а где-то посередине.
Как реализовать?
Сначала я прикидывал как это реализовать разными вариантами.
С помощью viewportchecker не получилось, т.к. при нахождении объекта в области видимости скрипт срабатывает постоянно и если делать анимацию появления элементов, то блок будет как бы появляться при каждой прокрутке.
С помощью слайдера (например owl-carousel, сделав вертикальную прокрутку) не получилось так как при пролистывании до конца при прокрутке дальше страница не листается ниже, остается на месте, и нужно уводить курсор из области слайдера чтобы пролистать дальше,
Потом я наткнулся на решение, которое приведено выше. Но решил обыграть немного по своему. И взял за основу высоту блоков относительно начального экрана, т.е. я как бы указал высоту от самого начала сайта до нужного для изменения блока и в скрипте прописал поправку на блоки которые предшествовали ему (например — 350vh). Но тут проблема в том что блоки которые предшествуют должны быть определенной высоты, таким образом я загоняю себя в эти рамки. И при изменении пропорций экрана это может стать серьезной проблемой.
jQuery(document).ready(function ($) {
// рабочая версия, но строгая привязка к высоте блоков
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var h = $(window).height();
if ( (scroll >= 2.5*h) && (scroll <= 3.5*h) ) {
jQuery('#intro-01, #intro-03').removeClass('active');
jQuery('#intro-02').addClass('active');
} else if (scroll >= 3.5*h) {
jQuery('#intro-01, #intro-02').removeClass('active');
jQuery('#intro-03').addClass('active');
} else {
jQuery('#intro-02, #intro-03').removeClass('active');
jQuery('#intro-01').addClass('active');
}
});
});
И тогда способ изменения состояния блока я сделал именно как описано в решении выше, только без компенсации (compensation), т.к. она нужна только для демонстрации (особенности верстки codepen.io), но при этом изменил сам принцип изменения блока.
Принцип
Блок с изменением контента при скроллинге разделен на 2 области:
- в первой содержатся набор блоков для изменения, первый из которых изначально активен (класс active). Эта область закрепляется к верху экрана со стилями position: fixed, top: 0, ну и в зависимости от верстки высотой height: 100vh;
- во второй области содержатся маркерные блоки которые запускают изменение состояния первого блока в зависимости от величины прокрутки. Этот блок невидимы, его высота составляет количество необходимых для изменения блоков.
Общий родительский блок должен иметь высоту по формуле: кол-во изменяемых блоков (кроме первого) + 1,5 экрана (1 экран для первого элемента который изначально активен, и 0.5 для последнего чтобы он не сразу проматывался а фиксировался еще некоторое время).
Верстка
<div class="our-values">
<div class="our-values-fixed">
<div class="our-values-title"><h2>Наши ценности</h2></div>
<div class="intros">
<div id="intro-01" class="intro active">
<div class="animate__animated animate__fadeInUp">Миссия:</div>
</div>
<div id="intro-02" class="intro active">
<div class="animate__animated animate__fadeInUp">Цели:</div>
</div>
<div id="intro-03" class="intro active">
<div class="animate__animated animate__fadeInUp">Философия:</div>
</div>
</div>
</div>
<div class="our-values-scroll">
<div class="our-values-scroll-01"></div>
<div class="our-values-scroll-02"></div>
</div>
</div>
Изменяемым элементам, которые непосредственно будут меняться, добавил стили animate (нужно подключить библиотеку).
Стили
.our-values {
height: 350vh;
position: relative;
}
.our-values-fixed {
position: sticky;
top: 0;
padding-top: 135px;
height: 100vh;
}
.intros {
position: relative;
}
.intro {
position: sticky;
bottom: calc(50vh + 6vw);
display: none;
}
.intro.active {
display: block;
}
.our-values-scroll {
height: 200vh;
}
.our-values-scroll > * {
height: 100vh;
}
Скрипт
jQuery(document).ready(function ($) {
$(document).scroll(function() {
// calculate where the sections start
var first_window = ($('.our-values-fixed').offset().top);
var second_window = ($('.our-values-scroll-01').offset().top);
var third_window = ($('.our-values-scroll-02').offset().top);
var footer = ($('footer').offset().top);
var scrollPos = $(document).scrollTop();
// Apply text changes
if (scrollPos < second_window) {
jQuery('#intro-02, #intro-03').removeClass('active');
jQuery('#intro-01').addClass('active');
}
else if (scrollPos >= second_window && scrollPos < third_window) {
jQuery('#intro-01, #intro-03').removeClass('active');
jQuery('#intro-02').addClass('active');
}
else if (scrollPos >= third_window && scrollPos < footer) {
jQuery('#intro-01, #intro-02').removeClass('active');
jQuery('#intro-03').addClass('active');
}
else { // дальше изменяемого блока
jQuery('#intro-01, #intro-02').removeClass('active');
jQuery('#intro-03').addClass('active');
}
});
});
[site-socialshare]