Этот курс ( Практикум по разработке CMS ) создавался, когда у PHP была версия 5.3 или 5.4. Со временем какие-то функции PHP устаревают (mysql, each), какие-то начинают работать по-другому (empty). Пожалуйста, следите за изменениями в PHP по сайту php.net! |
Серверные технологии
Фотогалерея - это просто
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 строк. В основном, это колдовство с Большой Картинкой и Стрелками вокруг неё (вправо-влево).