/ Scripts & jquery / Изменение контента при скроллинге

Изменение контента при скроллинге

25.01.2023

863

Пример реализации: 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]
  • Комментарии
  • Вложения

Добавить комментарий

Пока нет комментариев. Будь первым!

Изменение контента при скроллинге
Фиксированное меню 2.0
Рекомендации для васФиксированное меню 2.0Opttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.