Пример фотогалереи с использованием DOM

Фотогалерея, в которой увеличенные изображения можно выбирать без перезагрузки всей html-страницы. В примере используется Объектная модель документа(DOM), минимум XHTML-кода, немного CSS и JavaScript. Работает в Firefox1.02+, Opera7+, Internet Explorer5+, в других браузерах не проверял.

Пример фотогалереи с использованием DOM

Для простоты эксперимента условимся, что уменьшенных и увеличенных изображений одинаковое количество. У них одинаковые имена файлов, состоят из цифр(1, 2, 3 ... 25, 26 ... n), одинаковый тип файлов(например .jpg), а размещены они в разных директориях(например, smallimg и bigimg). Уменьшенные изображения все одинакового размера.

Однако эти ограничения приведены только для простоты конкретного эксперимента. При желании их список можно сократить, для этого потребуется лишь доработка CSS и JavaScript.

Сперва разметим место для увеличенного изображения div id="BigPhotoPlace".


? из ??

Создадим CSS и будем начнем описывать правила стилей. Разумеется, оформить галерею вы можете по своему вкусу. Здесь лишь пример. Далее большинство комментариев буду приводить в коде по ходу повествования.


.HorArrows { /* позиционируем стрелки навигации */
 clear:both;
 position:relative;
 height:38px;
}

Для увеличенного изображения определим div id="BigPhoto".


#BigPhotoPlace { /* увеличенное изображение */
 position:relative;
}
#BigPhoto { /* фиксируем размеры изображения */
 width:275px;
 height:340px;
 overflow:hiddden; /* прячем лишнее */
  /* на фоне можно написать что-то, пока
  изображение не загрузилось, будет этот текст */
 background:url(404.gif) no-repeat 0 0;
}

В div class="HorArrows" поместим стрелки навигации по галерее(вперед-назад). А также между ними разместим номер текущего изображения и общее количество картинок в галерее. ? напишем в CSS примерно следующее:


#BigPhotoPlace .HorArrows { 
/* навигация под увеличенной картинкой */
 text-align:center;
 margin:8px 0 0 0;
 width:275px; /* укажем ширину как у увеличенной картинки
 т.о. стрелки разместим по ее краям */
 position:relative;
}
.arrowRight { /* стрелка вправо */
 position:absolute;
 right:0;
 top:8px;
 cursor:pointer;
 cursor:hand;
}
.arrowLeft { /* стрелка влево */
 position:absolute;
 left:0;
 top:8px;
 cursor:pointer;
 cursor:hand;
}
#PhotoNum { /* информация о картинке */
 position:absolute;
 width:205px; /* ширина блока равна ширине
 поля с навигацией минус сумма ширины стрелок
 справа и слева */
 left:35px; /* отступ от левого края равен,
 либо больше ширины левой стрелки */
 top:4px;
}

По аналогии с увеличенным изображением делаем блок для уменьшенных div id="PreviewsPlace". Все уменьшенные изображения будем складывать в div id="Preview".


В блок навигации здесь, на мой взгляд, не имеет смысл включать количество изображений и номер текущего. При желании, его можно перенести из предыдущего блока навигации. Стоит обратить внимание на то, что id изображений в разных блоках навигации различаются(впрочем, и сами изображения можно заменить). В CSS добавим:


#PreviewsPlace { 
 width:345px; /* ширина блока по вкусу */
 position:relative;
 margin:0 0 0 20px;
}
#Preview { /* слой для кучи маленьких превьюшек */
 overflow:hidden;
 float:left;
}

А также сразу оформим внешний вид уменьшенных изображений:


.PrevImg { /* картинки маленьких превьюшек */
 margin:0 8px 8px 0;
 display: block;
 float:left;
 cursor:pointer;
 cursor:hand;
}

Прежде чем перейти к написанию скриптов, определимся, каким образом будем передавать скрипту настройки для галереи. Вероятно, я выбрал не самый оптимальный путь, но в данном случае так было проще. Я не знал каким образом будет собираться страница на сервере. Выбранный способ позволяет определить настройки для каждой страницы с галереей отдельно. Данные полей формы можно легко забрать и обработать с помощью JavaScript. А сами поля можно заполнить как вручную при кодировании страницы, так и с помощью серверных скриптов(Perl, PHP...), зависит от способа сборки страницы.

Минимум переменных, которые нам понадобятся в данном примере: общее количество изображений(ims), путь к уменьшенным(prevPath) и путь к увеличенным(photoPath). Поэтому закончим код вот такой формой:


А теперь самое время приступить к написанию JavaScript.

Далее приведен JavaScript код для фотогалереи, описания функций и некоторых особенностей выполнены в виде комментариев.


var PhorScrolls = new Array();
try {
 window.addEventListener('load', init, false);
} catch(e) {
 window.onload = init;
}
function init() {
// при загрузке страницы проверяем наличие
// слоев, в которые будем выводить изображения,
// информацию о них, а также есть ли настройки
    if (document.getElementById('Preview') &&
        document.getElementById('PrevSetup') &&
        document.getElementById('BigPhoto') &&
        document.getElementById('PhotoNum')){
    ownPreview = document.getElementById('Preview');
    BigImages = document.getElementById('BigPhoto');
    PhotoNums = document.getElementById('PhotoNum');
// считываем настройки галереи, условимся, что они есть
// хотя можно было бы проверять и их наличие
    setUps = document.getElementById('PrevSetup');
    ims = setUps.ims.value;
    prevPath = setUps.prevPath.value;
    bigImgPath =  setUps.photoPath.value;
// помещаем все параметры, необходимые для создания
// галереи в массив
    PhorScrolls[0] = new PhorScroll('Preview',
            'PtoRight',
            'PtoLeft',
            'ItoRight',
            'ItoLeft',
            'ims',
            'prevPath',
            'bigImgPath',
            'PhotoNum');
// и собираем галерею из уменьшенных изображений
    PhorScrolls[0].createPreviews();
// назначаем номер показываемой картинки,
// по-умолчанию = 1, т.е. первая.
if (!currPic){var currPic = 1;} 
    enLarge(currPic); 
        }
}
function PhorScroll(ownPrevID,
      toRightID,
      toLeftID,
      predID,
      sledID,
      NumImgs,
      prevPath,
      photoPath,
      PhotoNum) {
 this.index = PhorScrolls.length;
 this.prButton = document.getElementById(toRightID);
 this.plButton = document.getElementById(toLeftID);
 this.predButton = document.getElementById(predID);
 this.sledButton = document.getElementById(sledID);
 this.NumImgs = NumImgs;
 this.prevPath = prevPath;
 this.photoPath = photoPath;
 this.createPreviews = createPreviews;
 this.prevClick = prevClick;
 this.PredSledClick = PredSledClick;
}
// функция, в которой создадим массив уменьшенных изображений
// и выведем его результат на страницу
function createPreviews(){
 ImgArr = new Array();
 for (var i = 1; i  0) {
 for (h=0; h  0) {
 for (h=0; h  ims) {
    nextPhoto = 1;
    }
     enLarge(nextPhoto);
    evt.cancelBubble = true;
    return false;
}

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



Много комментариев (8) к “Пример фотогалереи с использованием DOM”

  1. Adepto :

    Отличное решение. Видел такое на американском сайте, только там картинки загружались сразу – что не есть хорошо (страница весила пол мегабайта).


  2. matt_reutt :

    очень здорово.
    спасибо)


  3. Dicos :

    Прекрасное решение, мне оно очень понравилось.


  4. Дядька Глюк :

    Решение то хорошее.. Только больше число картинок что-тоне шуршит. Плюс не ясно, будет ли работать скрипт, если картинки будут не попорядку – то есть не 1, 2,3,4 и т.д. а примерно так.. 1,2,3, 45, 78, 95, 146 и т.д. вот в чем вопрос..


  5. silex :

    2 Дядька Глюк
    Для ясности берем и тестируем :) У меня вообще было нестандартное размещение файлов: какждый файл с превьюхой в своей папке, имя файла произвольное. Ничего, полчаса – все решилось и адаптировалось…

    ЗЫ. Отличный скрипт :)


  6. Глеб :

    очень понравилось
    классный “движок”но то ли я чтото накосорезил адаптируя его под свои условия то ли одно из двух
    если будет возможность
    посмотрите что у меня из этого получилось
    http://pktgroup.narod.ru/foto/2ks/nz/gal.html

    360 фотографий
    приходится ждать пока все превьюшки не закачаются


  7. Глеб :

    все
    спасибо
    вроде сам разобрался
    http://pktgroup.narod.ru/foto/2ks/nz/gal.html
    может не оптимально но сделал чтобы превьюшки загружались не сразу а в процессе их же прокрутки


  8. Артур :

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