Бесконечная галерея с прокруткой

веб галерея

От автора: При работе с веб-галереями меня раздражает то, что приходится переходить со страницы на страницу; так что в сегодняшнем учебнике мы изучим, как создать автоматически генерируемую одностраничную бесконечную веб-галерею с прокруткой при помощи PHP и AJAX. Давайте начнем!


Перед тем, как мы приступим к практическим шагам, я Вам рекомендую просмотреть демо-результат работы.

Также скачайте исходники себе на компьютер!

Шаг 1: Эскиз проекта бесконечной галереи

Мы начнем с обычной страницы с галереей, у которой есть контейнер для изображений, и далее будем отслеживать позицию прокрутки, в течение коротких интервалов периодически вызывая функцию JavaScript. Каждый раз, когда полоса прокрутки нашей бесконечной галереи будет достигать нижней границы, мы будем делать запрос AJAX к внешнему файлу PHP, который возвращает список названий изображений. После этого, все, что нужно сделать – добавить эти изображения в контейнер, модифицируя, таким образом, высоту страницы и передвигая позицию прокрутки выше.

веб галерея

Шаг 2: Разметка HTML

Мы будем работать с очень стандартной разметкой: заголовок и контейнер для изображений. Уменьшенные изображения сгруппируем во множество из трех рядов, которые будут содержать ссылки на полноразмерные изображения. После каждой группы мы добавим текст, показывающий общее количество изображений, и ссылку к началу страницы.

<body>
	<div id="header">Web Gallery | Infinite Scroll</div>
	<div id="container">
		<a href="img/Achievements.jpg"><img src="thumb/Achievements.jpg" /></a>
		<a href="img/Bw.jpg"><img src="thumb/Bw.jpg" /></a>
		<a href="img/Camera.jpg"><img src="thumb/Camera.jpg" /></a>
		<a href="img/Cat-Dog.jpg"></a>
		<a href="img/CREATIV.jpg"></a>
		<a href="img/creativ2.jpg"></a>
		<a href="img/Earth.jpg"></a>
		<a href="img/Endless.jpg"></a>
		<a href="img/EndlesSlights.jpg"></a>    

		<p>9 Images Displayed | <a href="#header">top</a></p>
	    <hr />
	</div>
</body>

веб галерея

Шаг 3: CSS

CSS тоже довольно стандартный. Во-первых, мы определяем цвета страницы и местоположение заголовка и абзацев.

body{
	background:#222;
	color:#666;
}
#header{
	font-family:Arial, Helvetica, sans-serif;
	font-size:24px;
	font-weight:bold;
	text-align:left;
	text-indent:35px;
	margin: 0 auto;
	width:800px;
	margin-bottom:10px;
}
hr{
	margin: 20px;
	border:none;
	border-top: 1px solid #111;
	border-bottom: 1px solid #333;
}
p{
	color:#444;
	text-align:left;
	font-size:10px;
	margin-left: 20px;
	margin-bottom: -10px;
}
a{
	color:#444;
}

веб галерея

Шаг 4

Далее для контейнера и изображений я использовал чуть-чуть CSS3 для добавления закругленных углов и теней. Не забывайте, «-moz-box-shadow»и «-moz-border-radius» используются в Firefox, а «-webkit-box-shadow» и «-webkit-border-radius» — в Chrome и Safari.

веб галерея

#container{
	margin: 0 auto;
	width:800px;
	border:1px solid #333;
	-moz-border-radius: 10px;
	-webkit-border-radius: 10px;
	font-family:Verdana, Geneva, sans-serif;
	text-align:center;
}
img{
	border:10px solid #444;
	-moz-border-radius: 5px;
	-webkit-border-radius: 10px;
	margin: 15px;
}
img:hover{
	border-color:#555;
	-moz-box-shadow: 0px 0px 15px #111;
	-webkit-box-shadow: 0px 0px 15px #111;
}

Шаг 5: Скрипт PHP

Это очень короткое действие. Нам нужно вызвать скрипт PHP индексом следующего изображения, который нам нужен в качестве параметра. Прежде всего, мы должны извлечь все доступные имена изображений из каталога и сохранить их в массив. Я систематизировал свои изображения в две папки: «thumb» и «img», которые содержат соответственно уменьшенные и полноразмерные. Обратите внимание, что уменьшенные изображения должны иметь точно такие же имена, как соответствующие им изображения.

веб галерея

<?php

$dir = "thumb";
if(is_dir($dir)){
	if($dd = opendir($dir)){
		while (($f = readdir($dd)) !== false)
			if($f != "." && $f != "..")
				$files[] = $f;
	closedir($dd);
	} 

Здесь мы определяем переменную для каталога, из которого нам нужно получать изображения, проверяем, существует ли он и является ли доступным для чтения и считываем все имена файлов из него. При чтении полного содержимого папки, мы обязательно получим два дополнительных элемента, которые нам не нужны: «.» – это означает текущий каталог, и «..» – означает ссылку на родительский каталог. Чтобы учесть это, нам нужно проверять, отличается ли читаемый элемент от указанных двух, чтобы затем безопасно добавить его в свой массив.

$files[] = $f;

Заметьте, что при добавлении элемента в массив, если не указывать позицию куда он будет помещен, он будет помещен в конец массива.

Шаг 6

Теперь нужно построить текст ответа. Мы отошлем обратно в JavaScript одну строку, содержащую все необходимые имена файлов, разделенные точкой с запятой.

$n = $_GET["n"];
$response = "";

Здесь мы получаем в качестве параметра в URL индекс следующего нужного нам изображения и инициализируем строку ответа.

	for($i = $n; $i<$n+9; $i++)
		$response = $response.$files[$i%count($files)].';';
	echo $response;
}
?>

Как я уже говорил, картинки будут сгруппированы в наборы из трех рядов, где каждый ряд будет содержать по три изображения, так что нам нужно всего девять изображений, чтобы вернуть все имена файлов в группе. Начинаем с индекса, полученного в качестве параметра, $n, и двигаемся до $n+9. При каждом приращении добавляем имя изображения, за которым следует «;», в текст ответа. Тут происходит небольшой фокус. У нас нет бесконечного количества изображений; так что для создания эффекта «бесконечной», никогда не заканчивающейся галереи, мы должны сбрасывать в начало текущий индекс каждый раз, когда он становиться больше общего количества изображений. Это сделано с применением функции «modulo» или «%» между индексом и общим количеством изображений.

$i%count($files)

В результате этой операции мы получаем остаток от деления этих двух элементов. Например, если индекс «$i» равен «50″, а количество изображений «count($files)» равно «45″, результат будет равен «5″. Таким же образом, если «$i» — «50″, а «count($files)» — «65″, результат будет «50″. Наконец, нам необходимо отправить обратно текст ответа.

Шаг 7

Вот окончательный вариант скрипта для PHP. Просто поместите этот код в новый файл .php.

<?php

	$dir = "thumb";
	if(is_dir($dir)){
		if($dd = opendir($dir)){
			while (($f = readdir($dd)) !== false)
				if($f != "." && $f != "..")
					$files[] = $f;
			closedir($dd);
		} 

	$n = $_GET["n"];
	$response = "";
		for($i = $n; $i<$n+9; $i++){
			$response = $response.$files[$i%count($files)].';';
		}
		echo $response;
	}
?>

Шаг 8: JavaScript

Как обычно, сначала мы определяем переменные, которые нам позже понадобятся.

var contentHeight = 800;
var pageHeight = document.documentElement.clientHeight;
var scrollPosition;
var n = 10;
var xmlhttp;

веб галерея

Чтобы определить, находится ли полоса прокрутки вблизи низа страницы, нам нужны три переменные:

«contentHeight» – высота исходной галереи

«pageHeight» – высота видимой в браузере страницы

«scrollPosition» – позиция полосы прокрутки, отмеренная от верха

Наконец, нам нужна переменная для индекса следующей страницы (которую мы собираемся послать в PHP-скрипт) и переменная для объекта запроса Ajax.

Шаг 9

Здесь нам нужно определить функцию, которая добавит изображения в контейнер HTML.

function putImages(){
	if (xmlhttp.readyState==4){
    	if(xmlhttp.responseText){

Объект запроса проходит различные состояния после того, как запрос сделан, и у каждого состояния есть свое числовое обозначение. Нас интересует только одно значение — «4», которое означает финальную стадию, когда запрос окончен. Сначала проверяем, находится ли запрос в этом состоянии, а затем проверяем, получили ли мы отклик.

Шаг 10

Если выполнены оба условия, тогда нам нужно разобрать текст ответа на части. Это означает, что мы должны разделить имена файлов в массив. Помните, что скрипт PHP возвращает одну строку с именами, разделенными точкой с запятой. Вот пример: Achievements.jpg;Bw.jpg;Camera.jpg;Cat-Dog.jpg;CREATIV.jpg;creativ2.jpg;Earth.jpg;Endless.jpg;EndlesSlights.jpg;

var resp = xmlhttp.responseText.replace("\r\n", "");
var files = resp.split(";");

Имеется небольшая проблемка, с которой мы должны справиться в первую очередь; текст ответа может начинаться с символа перевода строки, который нам не нужен. Это легко исправить при помощи функции «replace», которая принимает два параметра: «\r\n» – символ перевода строки и «» – пустая строка, которая должна заменить все вхождения первого параметра. Теперь все, что нужно сделать – это разбить строку по разделителю «;».

Шаг 11

Далее мы должны добавить изображения в свой контейнер.

var j = 0;
for(i=0; i<files.length; i++){
    if(files<em></em> != ""){
        document.getElementById("container").innerHTML += '<a href="img/'+files<em></em>+'"><img src="thumb/'+files<em></em>+'" /></a>';
        j++;

        if(j == 3 || j == 6)
            document.getElementById("container").innerHTML += '';
        else if(j == 9){
            document.getElementById("container").innerHTML += '<p>'+(n-1)+" Images Displayed | <a href='#header'>top</a></p><hr />";
            j = 0;
        }
    }
}

Для каждого элемента массива мы делаем проверку, не пустая ли это строка, и добавляем уменьшенное изображение и ссылку на него. Также нам нужно использовать счетчик «j» для распределения изображений по рядам. После каждого третьего и шестого добавленного изображения мы создаем новую строку, а после девяти добавленных изображений вставляем текст, отражающий общее число показанных изображений и ссылку к верху страницы.

Шаг 12

Вот функция в завершенном виде.

function putImages(){
	if (xmlhttp.readyState==4){
    	if(xmlhttp.responseText){
			var resp = xmlhttp.responseText.replace("\r\n", "");
			var files = resp.split(";");

            var j = 0;
            for(i=0; i<files.length; i++){
                if(files<em></em> != ""){
                    document.getElementById("container").innerHTML += '<a href="img/'+files<em></em>+'"><img src="thumb/'+files<em></em>+'" /></a>';

                    j++;
                    if(j == 3 || j == 6)
                        document.getElementById("container").innerHTML += '';
                    else if(j == 9){
                        document.getElementById("container").innerHTML += '<p>'+(n-1)+" Images Displayed | <a href='#header'>top</a></p><hr />";
                        j = 0;
                    }
                }
            }
		}
	}
}

Шаг 13

Сейчас мы собираемся определить функцию, которая проверяет, приближается ли положение прокрутки к низу страницы, и делает запрос на сервер.

function scroll(){

	if(navigator.appName == "Microsoft Internet Explorer")
		scrollPosition = document.documentElement.scrollTop;
	else
		scrollPosition = window.pageYOffset;

Во-первых, нам нужно определить местоположение полосы прокрутки. Для Internet Explorer это делается немного по-другому, поэтому нам нужно проверить, каким браузером пользуется клиент, и затем просто сохранить это значение в переменной, которую мы ранее предусмотрели.

Шаг 14

if((contentHeight - pageHeight - scrollPosition) < 500){

веб галерея

Теперь проверяем, насколько далеко мы находимся от конца нашей галереи, т.е. не достигла ли видимая в браузере часть страницы расстояния в 500px от низа страницы. Это — не точная величина, и можно использовать любое другое значение, которое посчитаете подходящим. До тех пор, пока это условие верно, можно продолжать добавить новые изображения.

Шаг 15: Создание объекта XMLHttpRequest

Мы готовы создать объект XMLHttpRequest и отослать данные с помощью него. Снова повторяю, для Internet Explorer определения немного другие, так что мы также должны это учитывать.

if(window.XMLHttpRequest)
		//Firefox, Opera, Safari
		xmlhttp = new XMLHttpRequest();
	else
		if(window.ActiveXObject)
           	//Internet Explorer
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		else
			alert ("Bummer! Your browser does not support XMLHTTP!");

Шаг 16

Перед отправкой запроса нам нужно задать имя PHP-скрипта на сервере и добавить параметры, которые нужно ему придать.

var url="getImages.php?n="+n;

Это – простая текстовая переменная, представляющая URL страницы.

Шаг 17

Настало время отправить запрос.

xmlhttp.open("GET",url,true);
xmlhttp.send();

URL определяется вызовом метода «open». Второй параметр является единственно важным для нас, так как он обозначает URL скрипта. После этого все, что нам нужно – это отправить запрос с помощью send(). Это запустит PHP-скрипт, а результат его работы будет находиться в «xmlhttp.responseText».

Шаг 18

Последний шаг – разместить новый контент на странице, вызвав определенную ранее функцию «putImages», и подготовить переменные для следующего запроса.

веб галерея

n += 9;  
         contentHeight += 800;  
         xmlhttp.onreadystatechange = putImages;  
     }  
 }  

У нас в галерее девять новых изображений, таким образом, мы увеличиваем «n» на 9. Еще нам нужно изменить высоту страницы; поэтому увеличиваем «contentHeight» на 800.

Шаг 19

Вот использованный нами JavaScript целиком.

<script>
var contentHeight = 800;
var pageHeight = document.documentElement.clientHeight;
var scrollPosition;
var n = 10;
var xmlhttp;

function putImages(){

	if (xmlhttp.readyState==4)
	  {
		  if(xmlhttp.responseText){
			 var resp = xmlhttp.responseText.replace("\r\n", "");
			 var files = resp.split(";");
			  var j = 0;
			  for(i=0; i<files.length; i++){
				  if(files<em></em> != ""){
					 document.getElementById("container").innerHTML += '<a href="img/'+files<em></em>+'"><img src="thumb/'+files<em></em>+'" /></a>';
					 j++;

					 if(j == 3 || j == 6)
						  document.getElementById("container").innerHTML += '';
					  else if(j == 9){
						  document.getElementById("container").innerHTML += '<p>'+(n-1)+" Images Displayed | <a href='#header'>top</a></p><hr />";
						  j = 0;
					  }
				  }
			  }
		  }
	  }
}

function scroll(){

	if(navigator.appName == "Microsoft Internet Explorer")
		scrollPosition = document.documentElement.scrollTop;
	else
		scrollPosition = window.pageYOffset;		

	if((contentHeight - pageHeight - scrollPosition) < 500){

		if(window.XMLHttpRequest)
			xmlhttp = new XMLHttpRequest();
		else
			if(window.ActiveXObject)
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			else
				alert ("Bummer! Your browser does not support XMLHTTP!");		  

		var url="getImages.php?n="+n;

		xmlhttp.open("GET",url,true);
		xmlhttp.send();

		n += 9;
		xmlhttp.onreadystatechange=putImages;
		contentHeight += 800;
	}
}

Шаг 20

Последнее, что мы должны сделать, это запускать JavaScript периодически с заданным интервалом времени.

<body onload="setInterval('scroll();', 250);">

Просто определите свойство «onload» тэга «body» и установите его значение на функцию «setInterval». Это будет запускать функцию «scroll» каждую четверть секунды. Кроме того, вы можете изменить это значение времени, но я обнаружил, что оно оптимально для того, что нам нужно.

Конец!

Мы закончили создание галереи с бесконечной прокруткой! Надеюсь, вы нашли этот учебник полезным. Пожалуйста, оставьте сообщение внизу в отделе комментариев, если в дальнейшем вам понадобится помощь или совет.

Автор: Alexandru Pitea

Перевод и редакция: Рог Виктор и Андрей Бернацкий. Команда webformyself.

Источник: http://net.tutsplus.com

E-mail: contact@webformyself.com

Проект webformyself.com — Как создать свой сайт. Основы самостоятельного сайтостроения

P.S. Хотите опубликовать интересный тематический материал и заработать? Если ответ «Да», то жмите сюда.

JavaScript&jQuery с нуля до профи

Пройдите пошаговый видеокурс по JavaScript&jQuery

Научиться

Метки: , , , ,

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (5)

  1. Константин

    Хорошо описано

  2. Александр

    Хорошо описано, но сложно для новичков.

  3. Jelena

    демо-результат не работает :( (

  4. Ckazochnik

    У данного метода есть два больших недостатка.
    1. Фотографии подгружаются с небольшими тормозами.
    2. По страницам ориентироваться удобнее.

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree