Разработка ресурса использованием HTML, CSS, JavaScript,...

Click here to load reader

  • date post

    26-Jun-2020
  • Category

    Documents

  • view

    3
  • download

    0

Embed Size (px)

Transcript of Разработка ресурса использованием HTML, CSS, JavaScript,...

  • 1

    Санкт-Петербургский государственный университет Факультет филологии и искусств

    Кафедра информационных систем в искусстве и гуманитарных науках

    В . В . З А Х А Р К И Н А

    Р а з р а б о т к а в е б - р е с у р с а с и с п оль з о в а н и ем H T M L ,

    C S S , J a v a S c r i p t , P H P П р и м е н е н и е б а з о в ы х т е х н о л о г и й

    д л я с о з д а н и я ф о т о а р х и в а в в е б - и н т е р ф е й с е

    Санкт-Петербург

    2007

  • 2

    Рекомендовано к изданию

    Кафедрой информационных систем в искусстве и гуманитарных науках Факультета филологии и искусств Санкт-Петербургского государственного университета

    Захаркина В. В. Разработка веб-ресурса с использованием HTML, CSS,

    JavaScript, PHP. Применение базовых технологий для создания фотоархива в веб-интерфейсе: Учебное пособие. — СПб.: Ф-т филологии и искусств СПбГУ, 2007. — 49 с.

    Учебное пособие посвящено аспектам разработки фотоархива –

    типичного и актуального раздела многих современных информационных ресурсов глобальной сети Интернет. Рассмотрены вопросы компоновки веб-страницы, функционального дизайна и применения клиентских и серверных технологий. Изложение сопровождается иллюстрированными примерами. При обсуждении технологических аспектов рассмотренных примеров приводится программный код, обеспечивающий функциональность. Рассмотрены сценарии на языках JavaScript и PHP.

    Подготовка и издание учебного пособия осуществлено в рамках проекта СПбГУ «Инновационная образовательная среда в классическом университете» (Приоритетный национальный проект «Образование»).

    © В. В. Захаркина, 2007

    © Факультет филологии и искусств Санкт-Петербургского государственного университета, 2007

    Отпечатано с готового оригинал-макета в секторе цифровой печати Института искусств Факультета филологии и искусств СПбГУ

    199178 Санкт-Петербург, 10 линия В.О., д. 49.

    Подписано в печать 10.11.2007. Заказ № 47. Формат 60х84/16. Усл. печ. л. 3,25. Тираж 100 экз.

    3

    Вв ед е н и е Фотоархив (или фотогалерея) – типичный и актуальный раздел многих современных информационных ресурсов глобальной сети Интернет.

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

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

    Помимо этого, уже давно существует весьма значимое виртуальное сообщество фотографов – профессионалов и любителей. Многочисленные веб-ресурсы дают возможность опубликовать фотоматериалы и в интерактивном режиме проводить обсуждение их художественной (или иной) значимости.

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

  • 4

    Э т а пы с о з д а н и я в е б - р е с у р с а Кратко и в некоторой степени условно перечислим некоторые основные этапы разработки информационного веб-ресурса. Естественно, эта схема применима и для предмета нашего рассмотрения – фотоархива.

    • Первым этапом создания информационного ресурса любого содержания всегда является формулировка конечной цели.

    Для чего?

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

    • Проводится обзор аналогов.и анализ потенциальной аудитории. Формулируется диапазон параметров клиентского компьютера, на которые рассчитан веб-ресурс.

    • Предлагаеются варианты дизайнерского решения.

    • Параллельно с предложениями дизайнера-художника рассматриваются варианты функционального дизайна.

    • Предложенные варианты оцениваются с точки зрения удобства использования.

    • Между тем материал (в нашем случае, фотоматериал) уже как-то обрабатывается.

    • В конечном счете (впрочем, лишь на очередной итерации обсуждения) предлагается основной вариант компоновки и функциональности веб-документа.

    • Параллельно оценивается необходимость применения тех или иных технологий, предлагаются возможные программные решения. Особое внимение уделяется вопросам рационального сопровождения веб-ресурса.

    • Предлагаются параметры подготовки исходного материала и даются соответствующие указания.

    5

    • После этого параллельно работают верстальщик, создающий макет, и программист, обеспечивающий функциональность.

    • На этом этапе ответственный исполнитель проекта (или верстальщик) формулирует требования к форматам и качеству исходного материала. Окончательно определяется, кто отвечает за своевременную поставку и обработку материала.

    • Далее работают верстальщик и программист при участи дизайнера, итерационно корректируя постоянно меняющуюся концепцию.

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

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

    Предмет рассмотрения и структура изложения

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

    В большей или меньшей степени к рассмотрению будут привлечены вопросы

    • формирования дизайнерской концепции фотоархива в веб-интерфейсе,

    • вопросам функционального дизайна, • задания описания структуры веб-документа с помощью HTML, • определения параметров внешнего отображения с помощью CSS, • обеспечения интерактивности на стороне клиента с

    использованием сценариев JavaScript, • подходов к реализации серверных сценариев на языке PHP.

  • 6

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

    Используемые программные приложения

    • Adobe Photoshop – графический редактор. • Adobe Dreamweaver – средство разработки HTML-документов

    и организации сайта. • TextPad – текстовый редактор, ориентированный на создание

    программных кодов со встроенными анализаторами синтаксиса языков разметки и алгоритмических языков.

    • IrfanView – программа просмотра изображений с возможностью пакетного переименования и преобразования.

    • Apache webserver и его эмулятор Denver , работающий на клиентском компьютере под ОС Windows.

    Фун к ц и о н а л ь ный ди з а й н Пожалуй, в большинстве web-документов графические элементы играют декоративную или иллюстративную роль, а информационная роль остается за текстом. Однако при представлении, скажем, фотоархива или каталога выставки главной становится графика, а текст вторичен. При публикации графических архивов надо решить много вопросов: структурирование информации (при большом объеме архива - в виде базы данных), разработка удобной системы навигации, внешнее представление графики в web-документе.

    В этом разделе обсуждается компоновка элементов графического архива на web-странице и вопросы функциональности. Чаще всего пользователю предлагается набор миниатюр, соответствующих выбранному разделу архива, и так или иначе дается возможность просмотра полномасштабных изображений. Какого размера должны быть миниатюры, сколько их одновременно выводить на экран, как располагать, снабжать ли кратким текстовым описанием, как осуществить показ полномасштабного изображения - решение этих

    7

    вопросов зависит от особенностей графического материала и эстетических представлений разработчика (или заказчика).

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

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

    Приведу пример от далекого 1999 года. Фрагмент набора избранных фотографий Исаакиевского собора, полученных web-камерой, установленной интернет-центром Петербургского отделения фонда Сороса. Здесь все фотографии имеют одинаковые пропорции и размеры, поэтому оптимальный вариант - вывести их сплошным потоком. Вне зависимости от разрешения экрана и размера окна браузера миниатюры непринужденно перестраиваются. Полномасштабное изображение выводится в отдельном окне.

    Приведенный фрагмент скриншота имеет, на мой взгляд, определенное историческое значение. Обратите внимание на фразу «Click thumbnail to view image». В 1999 году пользователь мог не догадаться щелкнуть мышью по миниатюре, чтобы увидеть полномасштабную фотографию.

    Contents of St. Isaac's Cam views. Click thumbnail to view image.

  • 8

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

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

    • Все изображения одинакового размера (точнее, при предварительной обработке фотоматериала приведены к одинаковому размеру). В этом случае миниатюры также одинакового размера.

    • Изображения разного размера и разных пропорций. Но миниатюры представляют собой вырезанные и масштабированные фрагменты одинакового размера.

    • Изображения разного размера и разных пропорций. Миниатюры также имеют разные пропорции, но масштабированы таким образом, чтобы вписаться в квадрат заданных размеров. Кстати, именно такой вариант реализован в большинстве программ просмотра графических объектов. Так организован и вывод миниатюр в MS Windows «проводнике» в режиме «эскизы страниц».

    9

    Технологический аспект

    Этот простой вариант, в принципе, может быть реализован только с помощью HTML . Верстка такого варианта фотоархива в HTML элементарна: последовательно объявляются элементы img с соответствующими атрибутами. Если эту последовательность заключить в раздел с атрибутом ,

    миниатюры будут выровнены по центру.

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

    Итак, компоновка средствами HTML близка к идеалу. Но как быть с показом полномасштабной фотографии? Можно каждую миниатюру оформить как гиперссылку на полномасштабное изображение, и открывать целевой документ гиперссылки в новом окне. Однако в этом случае новые окна откроются с полным набором интерфейсных элементов: адресной строкой, панелями инструментов и т.д. Это некрасиво и нефункционально. К тому же, средствами HTML нельзя повлиять на размер и положение нового окна.

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

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

  • 10

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

    Технологический аспект

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

    Очевидно, что принципиальной разницы с точки зрения программирования между этим и предыдущим вариантом нет. В обоих случаях полномасштабное изображение выводится в отдельном окне. Следовательно, для удобной реализации просмотра придется привлечь язык клиентского программирования JavaScript .

    Вывод изображений во фреймах В предыдущих примерах полномасштабное изображение выводилось в отдельном окне. Однако, если позволяет экранное пространство, иногда уместно выводить крупное изображение во фрейме исходного окна. При этом можно все же одновременно вывести ряд миниатюр, а можно и заставить пользователя "пролистывать" изображения последовательно.

    11

    Компоновка в двух фреймах

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

    Представляются очевидными два естественных варианта компоновки. Выбор одного их них зависит от наличия на веб-странице прочих элементов: заголовков, навигационных панелей и т.д.

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

    Вопрос: как улучшить второй вариант? Естественный ответ: разместить фрейм с миниатюрами внизу, тогда полоса прокрутки будет выглядеть естественно и не испортит впечатления. А сколько еще таких вопросов возникает в процессе разработки…

    Технологический аспект

    Несмотря на, казалось бы, определенную структурную сложность, этот вариант может быть реализован исключительно средствами HTML. Это выгодно отличает его от предыдущих, явно требующих хотя бы минимального клиентского программирования.

  • 12

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

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

    "Пролистывание" изображений

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

    13

    Возможно, при реализации такого варианта будет уместна декоративная рамка, в которой показывается фотография. Видимо, потребуются рисованные «кнопки» щелчком по которым пролистываются фотографии. Кнопки можно, например, создать в редакторе Adobe Photoshop или отсканировать и обработать подходящее изображение.

    Пожалуй, естественным элементом при подобной компоновке будет подпись к фотографии. Сразу задумаемся над тем, что текст подписи в отдельных случаях может быть весьма объемным.

    Технологический аспект

    Структурная разметка при помощи HTML , скорее всего, не вызовет затруднений. Все элементы, представленные на скриншоте, легко располагаются в ячейках таблицы. Справа от скриншота тонким пунктиром показаны границы табличных ячеек. Фотография может быть выведена во встроенном фрейме iframe. Его границы выделены жирным пунктиром.

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

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

  • 14

    Первые два можно попробовать реализовать, если фотографий относительно немного.

    • Вырезать из каждой фотографии фрагменты одинаковых пропорций (хоть квадратные) и миниатюры сделать на их основе. Компоновка теперь не представляет трудностей.

    • Не стараться подгонять миниатюры под одинаковые пропорции. Более того, сделать их явно различающихся по размеру. Компоновку провести «вручную», стараясь создать гармоничную композицию.

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

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

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

    Если же пропорции существенно разные, подобный вариант, видимо, неприемлем:

    15

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

    Компоновка, хоть и не отличается изысканностью, приемлемо смотрится и, что самое главное для объемных архивов, абсолютно технологична. Сама формулировка идеи представления миниатюр звучит почти как алгоритм. Страницу с миниатюрами подобного типа удобно формировать динамически с помощью клиентского или серверного сценария.

  • 16

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

    Технологический аспект

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

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

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

    С другой стороны, посмотрим внимательно на миниатюру приведенного фрагмента скриншота. Неправда ли, это похоже на маленькую табличку из двух ячеек, в верхней из которых миниатюра, а в нижней – текст? Может быть, многие припомнят, что таблице HTML можно задавать параметр выравнивания align. Кстати, используется он относительно редко. Задание значений align=”left” или align=”right” не только прижимает таблицу к левой или правой границе документа, но и обеспечивает обтекание прочими элементами. Вставим наши миниатюры и подписи к ним в ячейки маленьких табличек с начальным тегом . Тогда браузер расположит эти таблички

    17

    таким образом, чтобы максимально использовать свободное пространство окна.

    Итак, только HTML и никаких сценариев JavaScript? Не совсем. Параметры выравнивания табличек, цвет и стиль их рамок, фоновые цвета следует задавать средствами CSS . Также с помощью CSS можно задать изменение цвета рамки при наведении курсора мыши.

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

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

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

    Ниже приведены два скриншота первого варианта веб-ресурса, посвященного храму Спаса Преображения на Нередице. Цифровые фотографии снимались разными фотоаппаратами и, следовательно, имеют разные пропорции. К тому же фотографии имеют различную ориентацию. Поэтому миниатюры, как предлагалось в разделе

  • 18

    «Компоновка миниатюр разных пропорций», вписаны в квадраты одинаковых размеров.

    Вывод фотографии полного масштаба должен сопровождаться текстовой аннотацией.

    Технологический аспект

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

    19

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

    Следовательно, единственное разумное технологическое решение – динамическое формирование страницы с фотографией. При этом могут быть использованы как клиентские (JavaScript), так и серверные (PHP) технологии.

    Кли е н т с к и е п р и емы п р о г р аммиров а н и я В этом разделе приведем фрагменты сценариев на языке JavaScript, которые реализуют технологические аспекты рассмотренных выше вариантов организации фотоархива. Эти сценарии не вполне рациональны: я старалась сделать их максимально понятными и прозрачными для тех, кто знаком лишь с основами JavaScript. Скорее, они представляют собой повод для размышления и основу для дальнейшей разработки.

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

    var s = 'начало очень длинной строки конец очень длинной строки';

    Для большинства языков (счастливое исключение – PHP) это просто синтаксически неправильно. Можно, конечно, придумать какой-нибудь значок, символизирующий вынужденный разрыв строкового литерала из-за особенностей печатного представления. Например, такой:

    var s = 'начало очень длинной строки конец очень длинной строки';

  • 20

    Иногда я буду его применять. Используя приведенный код, не забудьте вывести эти фрагменты на одной строке кода! А в ряде случаев длинные строковые литералы будут разбиты на фрагменты:

    var s = 'начало очень длинной строки' + 'конец очень длинной строки';

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

    Предполагается, что те, кто читает этот раздел, знакомы с языком структурной разметки HTML, возможностями каскадных таблиц стилей CSS и имеют представление об основах клиентского программирования на языке JavaScript.

    Вывод фотографии в отдельном окне

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

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

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

    21

    одно условное имя, задаваемое в качестве 2-го аргумента метода open(). В таком случае необходимо после загрузки нового содержимого активизировать окно, чтобы оно переместилось на передний план поверх других окон приложений. Здесь можно применить по крайней мере два подхода:

    • Передать фокус ранее открытому окну и изменить его размеры и положение, чтобы при новых размерах окно снова расположилось по центру экрана.

    • Закрыть окно с изображением, если оно уже было ранее открыто, а потом открыть новое окно нужного размера.

    Мне более рациональным представляется второй вариант. Впрочем, заинтересованному читателю предлагаю написать функцию, реализующую альтернативный подход. Отладив сценарий, сравните результаты и сделайте соответствующий вывод.

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

    //Объявляем глобальную переменную newWin без //инициализации. При вызове функции openWin() //ей будет присвоено значение объектного типа, //ссылающееся на новое окно. var newWin; function openWin(addr,w,h) //Открывает окно с условным именем 'new' //шириной w и высотой h и загружает в него //документ с адресом addr. //Окно располагается по центру свободной части //экрана. { //Закрываем окно, если оно ранее было открыто: if (newWin) newWin.close(); //Определяем координаты левого верхнего угла

  • 22

    //окна, используя свойства объекта Screen: var x = (screen.availWidth-w)*0.5; var y = (screen.availHeight-h)*0.5; //Открываем новое окно с указанным документом: newWin = window.open(addr,'new','width=' + w + ',height=' + h + ',left=' + x + ',top=' + y); };

    Компоновка в двух фреймах Суть компоновки: в одном фрейме выводится «лента» миниатюр, в соседнем – полномасштабная фотография. Остановимся на первом варианте из предложенных выше: миниатюры расположены одна под другой в вертикальном фрейме.

    Выше отмечалось, что такой вариант может быть реализован исключительно средствами HTML. Однако применение JavaScript может существенно улучшить удобство использования. Например, было бы удобно после щелчка по миниатюре, выведенной в отдельном фрейме, сдвигать «ленту» на одну позицию (скажем, вниз).

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

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

    Зададим классы стиля CSS для полномасштабной фотографии и сопровождающего текста. Например, так: div.largePhoto, div.photoText

    23

    { background:#FFFFFF; border:1px #AAAAAA solid; text-align:center } div.largePhoto { padding:15px } div.photoText { padding:5px }

    Можно предложить следующую реализацию в сценарии JavaScript. //-------------------------------------------- //Предполагаем, что фотографии находятся в //отдельном каталоге, а миниатюры – в его //подкаталоге, причем имена файлов //полномасштабных фотографий и миниатюр //совпадают. //Также предположим, что все изображения //сохранены в формате JPG. //В противном случае сценарий можно слегка //изменить. //Еще одно предположение: в общей структуре //документа два фрейма – с миниатюрами и //с полномасштабной фотографией – находятся //на одном уровне иерархии. //-------------------------------------------- //Определяем глобальные переменные: //имя фрейма вывода фотографии: photoFrameName = 'photo'; //каталог фотографий: photoDir = 'Images'; //каталог миниатюр: photoThumbDir = 'Images /Thumbs/'; //расширение графических файлов: photoExt = '.jpg';

  • 24

    //имена классов CSS для фотографии и //сопровождающего текста //(примеры задания стилей приведены выше): photoCSSClass = 'largePhoto'; photoTextCSSClass = 'photoText'; //-------------------------------------------- //Поскольку предполагается вывод фотографий с //подписями, в клиентском варианте //программирования удобно определить //массив строк, содержащих имя графического //файла (без расширения) и текст подписи. //Имя файла и текст в строке массива разделены //неким редко встречающимся символом: в нашем //случае это символ | //Описание массива в этом случае удобно хранить //в отдельном файле, присоединяя его к //документу, реализующему показ фотоархива. //Но сейчас мы определим массив в основном //тексте сценария: photoArr = new Array ( 'l07|Чтения по древнерусской литературе', 'l08|1982 г. Петрозаводск. На улице города', 'l09|1982 г. Петрозаводск. Д.С. Лихачев' // и так далее: перечисляем строковые //элементы массива ); //-------------------------------------------- //Определяем функцию вывода полномасштабной //фотографии. Она будет служить обработчиком //события click для миниатюр. Функция вызывается //как значение атрибута onClick,задаваемого //для каждой миниатюры с соответствующим //значением аргумента

    25

    //--------------------------------------------- function showPhoto(n) //Выводит n-ую полномасштабную фотографию с //сопровождающим текстом в фрейм, имя которого //задано в глобальной переменной photoFrameName. //Адреса фотографий и тексты подписей хранятся //в массиве photoArr { //выделяем из n-ого элемента массива photoArr[] //имя файла фотографии и текст подписи и //сохраняем в переменных photoName и photoText var w = photoArr[n].split('|'); var photoName = w[0]; var photoText = w[1]; //формируем содержимое документа фрейма с //именем photoFrameName with ( parent[photoFrameName].document ) { open(); write('' + '' + ''); write('' + '
    '+ '' + photoText + '');

  • 26

    write(''); close(); }; // with //сдвигаем «ленту» миниатюр таким образом, чтобы //выбранная миниатюра оказалась наверху: self.location.hash='#' + n; }; // function showPhoto

    //---------------------------------------------

    Этот сценарий должен быть задан в документе, содержащем миниатюры. Функция showPhoto() вызывается щелчком по миниатюре (обработчик onClick). Заметим, что HTML-описание самих миниатюр может быть выведено сценарием. Адреса графических файлов и текстовых описаний хранятся в массиве photoArr[], следовательно напрашивается вывод в цикле:

    for ( i=0; i< photoArr.length; i++ ) { //выделяем из i-ого элемента массива photoArr[] //имя файла фотографии и текст подписи и //сохраняем в переменных photoName и photoText var w = photoArr [i].split('|'); var photoName = w[0]; var photoText = w[1]; document.write( '
    \n'); };

    27

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

    Вызываться эта функция должна в ответ на щелчок мышью по «кнопкам», символизирующим переход

    вперед или назад.

    Кроме определения функции, обеспечивающей вывод указанной фотографии с текстом, в этом сценарии необходимо

    • запоминать в глобальной переменной номер текущей фотографии; • реализовать перемещение вперед и назад по массиву фотографий.

    Приведем код сценария. //-------------------------------------------- //Предполагаем, что фотографии находятся в //отдельном каталоге, а миниатюры – в его //подкаталоге, причем имена файлов //полномасштабных фотографий и миниатюр //совпадают. //Также предположим, что все изображения //сохранены в формате JPG. //В противном случае сценарий можно слегка //изменить. //Пусть фотография с текстом выводится во //встроенном фрейме iframe с именем, например, //photo //-------------------------------------------- //Определяем глобальные переменные: //имя фрейма вывода фотографии: photoIframeName = 'photo';

  • 28

    //ссылка на объект с именем photoIframeName: photoIframeObject = eval(photoIframeName); //каталог фотографий photoDir = 'Images'; //каталог миниатюр photoThumbDir = 'Images /Thumbs/'; //расширение графических файлов photoExt = '.jpg'; //имена классов CSS для фотографии и //сопровождающего текста //(примеры задания стилей приведены выше): photoCSSClass = 'largePhoto'; photoTextCSSClass = 'photoText'; //-------------------------------------------- //Поскольку предполагается вывод фотографий с //подписями, в клиентском варианте //программирования удобно определить //массив строк, содержащих имя графического //файла (без расширения) и текст подписи. //Имя файла и текст в строке массива разделены //неким редко встречающимся символом: в нашем //случае это символ | //Описание массива в этом случае удобно хранить //в отдельном файле, присоединяя его к //документу, реализующему показ фотоархива. //Но сейчас мы определим массив в основном //тексте сценария: photoArr = new Array ( 'l07|Чтения по древнерусской литературе', 'l08|1982 г. Петрозаводск. На улице города', 'l09|1982 г. Петрозаводск. Д.С. Лихачев'

    29

    // и так далее: перечисляем строковые //элементы массива ); //-------------------------------------------- //Определяем функцию вывода полномасштабной //фотографии. Она будет служить обработчиком //события click для миниатюр. //Функция вызывается как значение атрибута //onClick,задаваемого для каждой миниатюры с //соответствующим значением аргумента //--------------------------------------------- function showPhotoInIframe(n) //Выводит n-ую полномасштабную фотографию с //сопровождающим текстом в iframe, имя которого //задано в глобальной переменной photoIframeName //Адреса фотографий и тексты подписей хранятся в //ассиве photoArr { //выделяем из n-ого элемента массива photoArr[] //имя файла фотографии и текст подписи и //сохраняем в переменных photoName и photoText var w = photoArr[n].split('|'); var photoName = w[0]; var photoText = w[1]; //формируем содержимое документа встроенного //фрейма с именем photoFrameName. На объект с //этим именем ссылается переменная //photoIframeObject. with (photoIframeObject.document ) { open(); write('' + '

  • 30

    content="text/html;

    charset=windows-1251">' + ''); write(''+ '
    '+ '' + photoText + ''); write(''); close();

    }; // with

    }; // showPhotoInIframe //-------------------------------------------- //Обеспечим «пролистывание» фотографий //Инициализируем номер текущей фотографии nPhoto = 0; //-------------------------------------------- function prevPhoto() //Показывает предыдущую фотографию, изменяя //глобальную переменную nPhoto { if (nPhoto>0) { nPhoto = nPhoto-1; showPhotoInIframe(nPhoto) }

    }; // prevPhoto

    31

    //-------------------------------------------- function nextPhoto() //Показывает следующую фотографию, изменяя //глобальную переменную nPhoto { if (nPhoto

  • 32

    ов». Однако в этом случае никак не удается заставить все основные браузеры выполнить вертикальное выравнивание миниатюр по центру. А выравнивание по верхней границе выглядит некрасиво.

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

    Приведен фрагмент скриншота фотогалереи храма Спаса Преображения на Нередице. Верстка все-таки выполнена с помощью таблиц.

    Пусть максимальный размер миниатюры 150х150px. Размеры квадратной таблички должны быть несколько больше, например, 166ъ166px. Опишем класс CSS следующим образом: .thumb { margin:5px; border:1px #F4EBE2 solid; text-align:center; width:166px; height:166px; cursor:pointer; float: left; overflow:hidden } .thumb:hover { border:1px #664B3D solid }

    В предположении, что обработчиком onClick миниатюры является некая функция showPhoto(), задание миниатюры в HTML может быть таким:

    33

    Никакие дополнительные атрибуты таблицы или ячейки указывать не надо. Свободные поля вокруг таблицы и горизонтальное выравнивание содержимого ячейки задано с помощью CSS. Вертикальное же выравнивание содержимого табличной ячейки по умолчанию проводится по центру (align="middle"), что как раз нам и нужно.

    Вариант без фреймов и новых окон

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

    Пусть набор миниатюр выведен в разделе div с заданным значением атрибута id, например

    ... описания миниатюр ...

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

    Простейшая идея реализации показа полномасштабной фотографии при сохранении остальных элементов интерфейса состоит в замене содержимого указанного раздела с id="content" на динамически сформированное HTML описание фотографии, текста и ссылки

  • 34

    «назад». Приведем вариант функции, которую можно задать миниатюрам в качестве обработчика onClick.

    Символ я снова здесь применю в том случае, когда длинная инструкция JavaScript (например, строковый литерал) должна быть выведена в коде одной строкой , но не умещается по ширине печатной страницы. Фрагменты таких длинных инструкций в данном печатном издании будут разбиты на фрагменты, выводящиеся на разных строках. Используя приведенный код, не забудьте вывести эти фрагменты на одной строке кода!

    function showPhoto (photoAddr,photoWidth,photoHeight,legend) //photoAddr - путь к файлу изображения //photoWidth и photoHeight - ширина и высота //изображения //legend – подпись к изображению { //Сохраняем в строковой переменной прежнее //содержание раздела. //Оно будет использовано при формировании //ссылки «назад»

    previousHTML = document.getElementById('content').innerHTML; //формируем ссылку «назад», используя значение, //сохраненное в переменной previousHTML

    backLink = '

    << назад к миниатюрам

    '; //Формируем новое содержимое раздела: //ссылку «назад», фотографию и подпись

    newInnerHTML = backLink + '

  • 36

    • Научно-исследовательские проекты, существенную часть которых представляют архивы фотографий из семейных альбомов, музейных собраний и т.д.

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

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

    • Как преобразовать загруженные фотографии – ведь добрая половина пользователей способна прислать двухмегабайтный файл с изображением размера 3600х2400 пикселов.

    • С какими именами сохранять файлы на сервере: оставлять исходные или присваивать новые. Видимо, придется присваивать новые, так как имена присланных файлов вполне могу содержать недопустимые символы.

    • Каким образом создавать миниатюры: программным или вручную.

    Очевидно, без серверных технологий (например, PHP). в этом случае не обойтись. Поле выбора файла (элемент формы HTML input типа file) отобразить в странице загрузки не представляет труда. Но далее работают лишь серверные сценарии. Во-первых, надо организовать хранение загруженного графического файла и так или иначе создать миниатюру. Во-вторых, необходимо автоматически сформировать документ с миниатюрами на основании набора хранящихся на сервере файлов.

    Рассмотрим ряд аспектов создания серверных сценариев PHP, работающих с загруженными изображениями.

    37

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

    Рассмотрим два варианта. В первом миниатюры создаются вручную, а во втором – генерируются PHP масштабированием исходных изображений.

    Для определенности сделаем ряд предположений.

    • Компоновка страницы с миниатюрами простейшая, все миниатюры одинаковых размеров. Это предположение позволяет избежать громоздких описаний, не имеющих отношения к сути серверного программирования.

    • Фотографии находятся в отдельном каталоге, а миниатюры – в его подкаталоге, причем имена файлов полномасштабных фотографий и миниатюр совпадают.

    • Функция JavaScript, обеспечивающая вывод полномасштабной фотографии имеет имя showPhoto() и имеет три атрибута: имя файла фотографии (с расширением), ее ширина и ее высота в пикселах. Эта функция может быть описана в текущем документе или во внешнем файле.

    1. Миниатюры заготовлены вручную

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

  • 38

    миниатюр гораздо выше, чем если бы они создавались средствами PHP.

  • 40

    // Исходное изображение: $img = ImageCreateFromJpeg($srcImg); $w = imageSX($img); $h = imageSY($img); // Рассчитываем ширину и высоту миниатюры:

    if ($w>$h) { $w1 = $maxDim; $h1 = floor($h*$maxDim/$w); } else { $w1 = floor($w*$maxDim/$h); $h1 = $maxDim; }; // Масштабируем исходное изображение: // NB! // для PHP 5+ ImageCreateTrueColor() // для PHP 4 используем функцию ImageCreate() // Здесь приведен вариант для PHP 4

    $img_small = ImageCreate($w1,$h1);

    imageCopyResized($img_small,$img,0,0,0,0, $w1,$h1,$w,$h); // Отправляем миниатюру в браузер:

    header("Content-type: image/jpeg"); ImageJpeg($img_small); ?>

    Ссылка на файл create_thumb.php с приведенным выше кодом используется в сценарии основного файла. Для разнообразия, о отличие от предыдущего варианта сканирование каталога оформим в виде функции. Это может быть удобным при необходимости работы с различными каталогами.

    в отличие от предыдущего варианта будем выбирать из каталога только изображения в формате JPEG.

    41

  • 42

    onclick=\" showPhoto ('$photoPath/$f')\" >"; }; }; closedir($d); //закрываем каталог return(true); }; //___________________________________________ // Вызываем функцию для нужного каталога с // фотографиями:

    scanDir('Photo'); ?>

    Этот вариант, избавляющий от создания миниатюр вручную, почти во всем эффективнее предыдущего. Однако, качество миниатюр в общем случае будет ниже, чем при масштабировании в хорошем графическом редакторе.

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

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

    43

    В этой форме указан атрибут action="add_photo.php". Файл add_photo.php должен содержать сценарий, который проверяет тип загруженного файла, при необходимости выводит сообщения об ошибках загрузки и сохраняет файл на сервере, если ошибок нет. Приведем фрагмент такого сценария с минимальным количеством инструкций и параметров. Даже в этом случае объем кода не так уж мал.

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

  • 44

    if ( (@$_FILES['pict']['error']==0) && (@$_FILES['pict']['type'] == 'image/pjpeg') ) { $isUploadError = false; $fileName = basename($_FILES['pict']['name']); $fileFullName = $PhotoArcRootDir.'/'. $PhotoDir.'/'.$fileName; //если файл с таким именем уже существует: if ( file_exists($fileFullName) ) { $isUploadError = true; $errorMsg = $errorMsg. " Файл с именем $spanClassEmphErr  ".$fileName. "   уже существует в архиве сервера."; }; //если в имени файла есть //недопустимые символы : if ( $fileName!=UrlEncode($fileName) ) { $isUploadError = true; $errorMsg = $errorMsg. " Недопустимые символы в имени файла $spanClassEmphErr  ".$fileName."  . "; }; }

    //----------------------------------------- //Если была ошибка загрузки или не тот тип //файла:

    45

    else { $isUploadError = true; }; //Формируем сообщения об ошибках. //Если были ошибки загрузки или файл не типа //JPEG: if ($isUploadError) { if ($_FILES['pict']['error']>0) { switch ( $_FILES['pict']['error'] ) { case 1: $errorMsg = $errorMsg. 'Размер файла превышает допустимый. '; break; case 2: $errorMsg = $errorMsg. 'Размер файла превышает допустимый. '; break; case 3: $errorMsg = $errorMsg. 'Файл загружен лишь частично вследствие ошибки сервера.'; break; case 4: $errorMsg = $errorMsg. 'Не выбран файл для загрузки.; break; }; } elseif ($_FILES['pict']['type'] != 'image/pjpeg') $errorMsg = 'Недопустимый тип файла; фотография должна иметь формат JPEG.'; echo '

  • 46

    } else //--------- если все в порядке:

    copy($_FILES['pict']['tmp_name'], fileFullName); ?>

    Нетрудно заметить, что без обработки возможных ошибок от этого фрагмента сценария, помимо объявления глобальных переменных, остались бы три инструкции, которые можно свести и в одну: $fileName = basename($_FILES['pict']['name']); $fileFullName = $PhotoArcRootDir.'/'. $PhotoDir.'/'.$fileName; copy($_FILES['pict']['tmp_name'],$fileFullName);

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

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

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

    Ли т е р а т у р а • Кирсанов Д. Веб-дизайн. СПб., 1999. 358 с.

    • Пауэлл Т. Web-дизайн. СПб.: БХВ-Петербург, 2004. 1045 с.

    • Вин Д. Искусство web-дизайна. СПб.: Питер, 2003. 218 с.

    47

    • Спейнаур С., Экштейн Р. Справочник вебмастера. СПб.: O'Reilly, 2001. 604 c.

    • Флэнеган Д. JavaScript. СПб.: O'Reilly, 2004. 955 c.

    • Мак-Федрис П. Использование JavaScript. М.-СПб.-Киев, 2002. 895 с.

    • Котеров Д. PHP 4. СПб.: БХВ-Петербург, 2001. 576 с.

    • Котеров Д., Костарев А. PHP 5. СПб.: БХВ-Петербург, 2005. 1120 с.

    • HTML 4.01 Specification. W3C Recommendation 24 December 1999 http://www.w3.org/TR/html401/ Информация из первоисточника (на английском языке). Спецификация HTML 4.01 . Рекомендация W3C от 24 декабря 1999

    • Спецификация HTML 4.01 . Рекомендация W3C 24 декабря 1999 http://www2.stack.ru/~julia/HTML401/cover.phtml Перевод Юлии Поданевой

    • Cascading Style Sheets, level 2. CSS2 Specification. W3C Recommendation 12-May-1998 http://www.w3.org/TR/REC-CSS2 Сведения из первоисточника (на английском языке). Каскадные таблицы стилей второго уровня. Спецификация CSS2. Рекомендация W3C от 12 мая 1998 г.

    • Каскадные таблицы стилей второго уровня. Спецификация CSS2. Рекомендация W3C от 12 мая 1998 г. http://loc.stack.ru/projects/CSS2/cover.html Перевод официальной спецификации Юлии Поданевой.

    • JavaScript Documentation http://developer.netscape.com/docs/manuals/index.html?content=javascript.html Документация по Client-Side JavaScript (на английском языке). JavaScript 1.2, 1.3, 1.4, 1.5. Справочники. DOWNLOAD. Инструменты, статьи, Plug-ins.

    • JavaScript-1.5 Reference http://www.mozilla.org/js/spidermonkey/apidoc/complete-frameset.html Документация по Client-Side JavaScript 1.5 (на английском языке).

  • 48

    • JavaScript Developer Central http://developer.netscape.com/tech/javascript/index.html Документация по JavaScript от Netscape (на английском языке).

    • JavaScript Guide http://developer.netscape.com/docs/manuals/communicator/jsguide4/index.htm Документация по ядру и расширениям JavaScript (на английском я