Взаимодействуем с контентом по скроллу (scroll event) | Блог веб-разработчика MaxGraph

Взаимодействуем с контентом по скроллу (scroll event)

Привет! Сегодня интересная темка. Расскажу, как сделать какие-либо действия для блоков по скроллу. Для примера просто взял цвет и по скроллу будем задавать цвет (когда блок начнет появляться в зоне видимости). Поехали!

Итак, как же управлять скроллом? Да на самом деле все лежит в банальных математических вычислениях высоты (ширины). Разберемся детальнее:

HTML

1
2
3
4
5
6
7
8
9
10
<div class="item" data-color="#CD5C5C"></div>
<div class="item" data-color="#98FB98"></div>
<div class="item" data-color="#FF1493"></div>
<div class="item" data-color="#FFFF00"></div>
<div class="item" data-color="#00CED1"></div>
<div class="item" data-color="#8A2BE2"></div>
<div class="item" data-color="#191970"></div>
<div class="item" data-color="#778899"></div>
<div class="item" data-color="#FFD700"></div>
<div class="item" data-color="#000000"></div>
<div class="item" data-color="#CD5C5C"></div>
<div class="item" data-color="#98FB98"></div>
<div class="item" data-color="#FF1493"></div>
<div class="item" data-color="#FFFF00"></div>
<div class="item" data-color="#00CED1"></div>
<div class="item" data-color="#8A2BE2"></div>
<div class="item" data-color="#191970"></div>
<div class="item" data-color="#778899"></div>
<div class="item" data-color="#FFD700"></div>
<div class="item" data-color="#000000"></div>

Имеем 10 блоков с классом item и data-color. Этот дата-атрибут нужен, чтобы задать нужный цвет блоку.

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: sans-serif;
}
 
body {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 100px;
}
 
.item {
  width: 500px;
  height: 500px;
  border: 1px solid #000;
  border-radius: 4px;
  margin-bottom: 100px;
  transition: all 0.3s ease-in-out;
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: sans-serif;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 100px;
}

.item {
  width: 500px;
  height: 500px;
  border: 1px solid #000;
  border-radius: 4px;
  margin-bottom: 100px;
  transition: all 0.3s ease-in-out;
}

Просто расставляем блоки по центру и даем им отступы. А так же даем бордер, чтобы их вообще было видно изначально.

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
let $item = $('.item');
 
let $window = $(window);
 
function viewedItem() {
    let scrollTop = $window.scrollTop();
 
    let scrollBottom = scrollTop + $window.height();
 
    $item.each((index, item) => {
        let $currentItem = $(item);
    
        let itemOffsetTop = $currentItem.offset().top;
 
        let itemOffsetBottom = itemOffsetTop + $currentItem.height();
 
        if (scrollTop < itemOffsetBottom && scrollBottom > itemOffsetTop && !$currentItem.attr('data-viewed')) {
      let color = $currentItem.attr('data-color');
      $currentItem.css('background-color', color);
            $currentItem.attr('data-viewed', true);
        }
    });
}
 
viewedItem();
 
$(window).scroll(() => {
    viewedItem();
});
let $item = $('.item');

let $window = $(window);

function viewedItem() {
	let scrollTop = $window.scrollTop();

	let scrollBottom = scrollTop + $window.height();

	$item.each((index, item) => {
		let $currentItem = $(item);
    
		let itemOffsetTop = $currentItem.offset().top;

		let itemOffsetBottom = itemOffsetTop + $currentItem.height();

		if (scrollTop < itemOffsetBottom && scrollBottom > itemOffsetTop && !$currentItem.attr('data-viewed')) {
      let color = $currentItem.attr('data-color');
      $currentItem.css('background-color', color);
			$currentItem.attr('data-viewed', true);
		}
	});
}

viewedItem();

$(window).scroll(() => {
	viewedItem();
});

Магия здесь! Поехали разбираться)

  1. Создаем функцию viewedItem. Сразу получаем текущий скролл от начала документа в переменную scrollTop. И после этого получаем так же определение scrollBottom, сложив наш скролл и высоту окна браузера. Таким образом мы сможем ловить события не когда начало экрана туда попало, а еще и когда конец. Но об этом дальше.
  2. Пробегаемся по всем нашим блокам с помощью each. Получаем в переменную $currentItem текущий блок и тут же рассчитываем для него расстояние от начала документа и расстояние + высоту. (стоит сделать ремарку — для статичных блоков мы высчитываем это значение один раз, оно сохраняется и все. А вот переменная scrollTop постоянно меняется, т.к. мы использовали там scrollTop, а не offset().top).
  3. А дальше — простые сравнения. Смотрим, чтобы расстояние скролла окна было всегда меньше чем расстояние + высота блока, а так же расстояние + высота окна были больше чем расстояние блока от начала. Таким образом, как только блок попадает в поле видимости — с ним что-то происходит.
  4. И да, там есть еще одно условие — проверяется data-viewed у блока. Напомню, что изначально его нет у блоков. По сути, это просто дата-атрибут — флаг, который позволяет скрипту понять, что над этим блоком уже действия произвелись, значит его трогать уже не надо.
  5. Ну и в самом условии просто берем у текущего элемента его data-color и даем background-color: текущий цвет.
  6. Вызываем функцию один раз чтобы при загрузке страницы уже сработало один раз наше действие. А затем вызываем ее на скролл, чтобы на каждый скролл проверялось наше условие. Вот и все)

 

И конечно, пен:

 

Надеюсь, данная тема была Вам полезна. Оставляйте свои отзывы и до скорого)

Метки: , , ,

Понравилось? Оцени!
12345 (2 оценок, среднее: 5,00 из 5)
Загрузка...

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *