Действие при появлении элемента на экране — jQuery

Действие при появлении элемента на экране — jQuery

С каждым днем сайты становятся все сложнее, а дизайнеры придумывают все новые способы привлечь внимание посетителей - и это правильно, ведь удивить становится все труднее. Именно поэтому в последнее время на многих сайтах присутствует анимация и различные эффекты. Но нас сегодня интересует немного другая тема: как определить, виден ли сейчас элемент на экране или нет? И если виден, то сделать какое-нибудь действие. Например перекрасить его в другой цвет. Сайт может быть длинным и если вы назначите анимацию при загрузке страницы, вероятность того, что пользователь ее увидит - очень мала - нужно запускать ее в тот момент, когда элемент появился на странице. Давайте научимся это делать.

Для начала создадим небольшую разметку, с помощью которой мы будем проводить свои эксперименты:

<div class="page-site">
	<div class="block">Привет! Я блок!</div>
</div>

Одна обертка и один блок. Добавим немного стилей:

.page-site {
	position:relative;
	height:5000px;
}
.block {
	width:200px;
	height:200px;
	background:red;
	text-align:center;
	color:#fff;
	font-family:Arial;
	font-size:18px;
	line-height:200px;
	position:absolute;
	top:50%;
	margin-top:-100px;
	left:50%;
	margin-left:-100px;
}
.block.green {
	background:green;
}

Как видите, мы задали высоту обертке и поставили блок по центру - при загрузке страницы его не видно. И заранее описали класс green при котором заливка блока станет зеленой.

Давайте попробуем перекрасить блок, как только он целиком попадет в область видимости экрана.

Для этого напишем следующий скрипт:

$(document).ready(function() {
	var windowHeight = $(window).height();
 
	$(document).on('scroll', function() {
		$('.block').each(function() {
			var self = $(this),
			height = self.offset().top + self.height();
			if ($(document).scrollTop() + windowHeight >= height) {
				self.addClass('green')
			}
		});
	});
});

Я немного забежал вперед и предусмотрел наличие на странице сразу множества элементов, поэтому использовал each. Что делает скрипт: при скролле страницы он пробегает все элементы и проверяет, что расстояние до них + их высота меньше расстояния, которое пользователь пролистал + высота окна. Как только условие нарушается, срабатывает скрипт - в нашем случае он добавляет класс green.

Если вам нужно многократное повторение действия (отмена действия если элемент скроется и повтор - если опять появится), достаточно просто дописать условие else.


Если блок по высоте больше высоты экрана

Если блок очень высокий, то он целиком не поместится в экран, а значит что скрипт выполнится поздно. Для такого случая давайте немного модифицируем скрипт. Будем выполнять действие, когда до верха страницы будет оставаться 100px.

Немного обновим стили:

.page-site {
	position:relative;
	height:5000px;
}
.block {
	width:200px;
	height:1200px;
	background:red;
	text-align:center;
	color:#fff;
	font-family:Arial;
	font-size:18px;
	line-height:200px;
	position:absolute;
	top:50%;
	margin-top:-600px;
	left:50%;
	margin-left:-100px;
}
.block.green {
	background:green;
}

И теперь сам модифицированный скрипт:

$(document).ready(function() {
	var windowHeight = $(window).height();
 
	$(document).on('scroll', function() {
		$('.block').each(function() {
			var self = $(this),
			height;
			if (self.height() >= windowHeight) {
				height = self.offset().top + windowHeight - 100;
			} else {
				height = self.offset().top + self.height();
			}
			if ($(document).scrollTop() + windowHeight >= height) {
				self.addClass('green')
			}
		});
	});
});

В скрипте мы выполняем проверку - если элемент больше чем высота экрана, то скрипт сработает, когда до верха останется 100px, в противном случае сработает по "старой" схеме.


Действие по центру экрана

А что если действовать нужно в тот момент, когда элемент находится ровно по центру экрана? И для такого случая найдется свой скрипт:

$(document).ready(function() {
	var windowHeight = $(window).height();
 
	$(document).on('scroll', function() {
		$('.block').each(function() {
			var self = $(this),
			height = self.offset().top + self.height()/2 - windowHeight/2;
			if ($(document).scrollTop() >= height) {
				self.addClass('green');
			}
		});
	});
});

Вот и все. Всем удачи!

03.05.17
Для просмотра сайта обновите браузер.