Опубликован: 22.10.2016 | Уровень: для всех | Доступ: платный
Лекция 4:

Серверные технологии

< Лекция 3 || Лекция 4: 1234

Фотогалерея - это просто

Php: выводим список картинок-миниатюр, у которых в атрибутах src указываем путь к маленькому изображению (такие изображения-миниатюры хранятся в папке files/th/0/). Каждая картинка (html элемент IMG) обёрнута в ссылку – html-элемент A с атрибутом href="path_to_bigPhoto" (путь к большому изображению, которое хранится в папке files/0/). Весь список помещаем в контейнер div (например) с уникальным идентификатором, содержащим наименование функции javascript. Функция php, вычисляющая уникальность идентификатора для каждого такого "виджета", копит эти идентификаторы в массиве Page::$config['markers'], а потом в конце страницы мы пишем javascript, который, во-первых, перечисляет массив всех "видждетов", потом по очереди вызывает функции, собранные в этом массиве (Catalog, Form, YMap...):

dict.markers = {"catalog":[{"num_id":1,"subj":"catalog","real":false}]}
initMarkers();

Все javascript-обработчики для Каталога, Формы или других задач хранятся в объектах и пишутся в javascript-коде с большой буквы; на сервере же все они пишутся с маленькой буквы и список в результате генерируется почему-то тоже с маленьких букв. Поэтому функция последовательного вызова обработчиков (initMarkers) должна преобразовывать наименования вызываемых объектов с помощью пользовательской функции capitalize.

Javascript: функция инициализации Каталога init() ищет в переданном по идентификатору элементе div картинки с условной меткой (в нашем случае это class="thumb"). Картинки заносятся в список. Этот список может служить основой для всяческих "лент" и "слайдеров". Весь код занимает 90 строк:

var Catalog = {
	img_list: [],
	micro_list: [],
	kolhoz: true,
	tN: 'img',
	cN: 'thumb',
	init: function (id, subj) {
		var box = gi(id);
		if (box) {
			this.img_index = 0
			box.img_list = [];
			box.Big = this.getBig(box); //для Большой Картинки
			//this.box.micro_list = []; //будущая микронавигация
			//box.micro = ce('div');
			//cc(box.micro, 'micro')
			box.img_index = 0;
			setE(box, this.tN, {className:this.cN}, 
			  {onclick:Catalog.showBig, box:box}, 
			  'inList', 'Catalog')
			this.addLister(box.Big)
		}
	},
	
	inList: function (el){
		Catalog.img_list[Catalog.img_index] = el 
		  //Для слияния разных контейнеров с фото
		el.box.img_list[el.box.img_index] = el
		el.c_num = Catalog.img_index
		//el.micer = el.box.micro.insertBefore(ce('span'), 
    el.box.micro.firstChild)
		Catalog.img_index += 1
		el.box.img_index += 1
		Catalog.addEditLink(el);
	},
	
	addEditLink: function (el){
		el.item = findParent(el, 'div', 'item');
		var carr = el.className.split(/\s/);
		if (Editor.editable) {
			ac(buildEl2('span', {sql:['_edit', 'file', carr[1]], className:'_edit2', 
	onclick:Editor.preBuildForm, el:el.parentNode}, 'Редактировать file ' + carr[1]), el.item)
		
			cc(el.item, '_edit')
		}
	},
	
	addLister: function (Big){
		var pre = {prev:'prevI', next:'nextI'};
		if (!Big.prev) {
			for (var id in pre) {
 Big[id] = ac(buildEl2('div', {className:pre[id], onclick: Catalog.showNext}), Big);
			}
		}
	},
	
	getBig: function (box){
		return (box.Big) 
			? box.Big
			: ac(buildEl2('div', {className:'bigImgBox disnone'}));
	},
	
	getBigI: function (Big){
		if (!Big.BigI) {
			var tC = ac(buildEl2('div', {className:'tCell'}), Big);
			Big.BigI = ac(buildEl2('img', {className:'bigImg'}), tC);
		}
		return Big.BigI;
	},
	
	showBig: function (e, o){
		prevent(e);
		o = o || this; //img (thumb)
		var Big = o.box.Big;
		Catalog.getBigI(Big).src = o.parentNode.href;
		Hider.show(Big);
		Big.prev.img = o;
		Big.next.img = o;
		window.scrollTo(0,0)
	},
	
	showNext: function (e, o){
		o = o || this
		var img = o.img, idx = img.c_num, img2, box = img.box, img_list = box.img_list;
		idx = (hc(o.className, 'nextI')) ? idx – 1 : idx + 1
		img2 = img_list[idx]
		//cc(img.micer, null, 'curr') //будущая микронавигация
		//cc(img2.micer, 'curr')
		if (img2) {
			Catalog.showBig(null, img2)
			box.Big.prev.img = img2
			box.Big.next.img = img2
		}
	}
}

При щелчке по картинке создаётся (или используется раньше созданный) DIV 800 х 600 пикселов (можно другой размер), в него помещается элемент IMG с src, взятым из атрибута href ссылки, в которую обёрнута каждая миниатюра.

Картинок много, и хотелось бы их листать, "не отходя от витрины". Добавляем к контейнеру большого изображения стрелки вправо и влево (next, prev). К стрелкам присоединяем javascript-функцию showNext, которая ищет в списке картинок следующую картинку (по индексу текущей картинки +- 1) и отображает в большом окне эту новую картинку.

Список картинок хранится как свойство текущего контейнера. Если на странице несколько таких контейнеров (несколько разных групп фото), они не пересекаются. Но у нас зарезервировано свойство kolhoz: можно указывать его true и в этом случае хранить список картинок как свойство общего объекта Catalog (при листании будут показываться все фото из разных групп страницы подряд). Это дольше описывать, чем реализовать (2-3 строчки кода).

Зарезервировано ещё несколько строк для микронавигации. Часто можно увидеть на сайтах под большой картинкой такие кружочки (или квадратики), символизирующие список всех фото. Это тоже несложно добавить – больше кода, наверное, будет в CSS.

Кстати, о CSS: общий css сайта пока не превышает 8 килобайт, и Каталогу там посвящено примерно 30 строк. В основном, это колдовство с Большой Картинкой и Стрелками вокруг неё (вправо-влево).


Рис. 4.1.

Рис. 4.2.

Рис. 4.3.

Рис. 4.4.

Рис. 4.5.

Рис. 4.6.
< Лекция 3 || Лекция 4: 1234
Михаил Гутентог
Михаил Гутентог

Этот курс ( Практикум по разработке CMS ) создавался, когда у PHP была версия 5.3 или 5.4. Со временем какие-то функции PHP устаревают (mysql, each), какие-то начинают работать по-другому (empty). Пожалуйста, следите за изменениями в PHP по сайту php.net!

Александр Мельников
Александр Мельников

Изучаю курс "Практикум по созданию CMS" в листинге 4.3

$n = count($_GET); if ($n > 0) { $param = each($_GET); // самое простое: пропускаем только первый параметр if ($n > 1 || !isset($valid[$param['key']])) { _404(); }

При попытке просмотра в браузере получаю ошибку: Deprecated: The each() function is deprecated.  И не пойму как исправить ситуацию.

Елена Суханова
Елена Суханова
Россия, Москва, МИЭТ, 2011
Анастасия Щитова
Анастасия Щитова
Россия, Москва, ФГБОУ ВО "Московский государственный юридический университет имени О.Е. Кутафина (МГЮА)", 2016