- •Введение
- •Несколько слов о книге
- •Глава 1. Каким должен бытъ Web-интерфейс
- •Действия пользователя при работе с приложением
- •Накладные расходы при работе в сети
- •Асинхронное взаимодействие
- •Независимый и переходный образы использования
- •Четыре основных принципа Ajax
- •Браузер имеет дело с приложением, а не с содержимым
- •Сервер доставляет данные, а не содержимое
- •Реальное кодирование требует порядка
- •Применение богатых клиентов Ajax
- •Системы, созданные с использованием Ajax
- •Google Maps
- •Альтернативные технологии
- •Macromedia Flash
- •Java Web Start
- •Резюме
- •Ресурсы
- •Основные элементы Ajax
- •JavaScript изучался не зря
- •Определение внешнего вида с помощью CSS
- •Селекторы CSS
- •Свойства стилей
- •Простой пример использования CSS
- •Обработка DOM с помощью JavaScript
- •Поиск узла DOM
- •Создание узла DOM
- •Добавление стилей к документу
- •Свойство innerHTML
- •Асинхронная загрузка с использованием XML
- •Элементы IFrame
- •Объекты XmlDocument и XMLHttpRequest
- •Использование фуниции обратного вызова для контроля запроса
- •Жизненный цикл процедуры поддержки запроса
- •Отличия Ajax от классических технологий
- •Резюме
- •Ресурсы
- •Порядок из хаоса
- •Образы разработки
- •Реструктуризация и Ajax
- •Во всем надо знать меру
- •Реструктуризация в действии
- •Варианты применения реструктуризации
- •Несоответствие браузеров: образы разработки Fagade и Adapter
- •Управление обработчиками событий: образ разработки Observer
- •Повторное использование обработчиков событий: образ разработки Command
- •Обеспечение единственной ссылки на ресурс: образ разработки Singleton
- •"Модель-представление-контроллер "
- •Серверная программа Ajax, созданная без применения образов разработки
- •Реструктуризация модели
- •Разделение содержимого и представления
- •Библиотеки независимых производителей
- •Библиотеки, обеспечивающие работу с различными браузерами
- •Компоненты и наборы компонентов
- •Элементы, располагаемые на стороне сервера
- •Резюме
- •Ресурсы
- •Применение архитектуры MVC к программам различных уровней
- •Применение архитектуры MVC к объектам, присутствующим в среде браузера
- •Представление в составе Ajax-приложения
- •Отделение логики от представления
- •Отделение представления от логики
- •Контроллер в составе Ajax-приложения
- •Классические JavaScript-обработчики
- •Модель обработки событий W3C
- •Реализация гибкой модели событий в JavaScript
- •Модель в составе Ajax-приложения
- •Использование JavaScript для моделирования предметной области
- •Взаимодействие с сервером
- •Генерация представления на основе модели
- •Отражение объектов JavaScript
- •Обработка массивов и объектов
- •Включение контроллера
- •Резюме
- •Ресурсы
- •Программы, выполняемые на сервере
- •Создание программ на стороне сервера
- •N-уровневые архитектуры
- •Управление моделью предметной области на стороне клиента и на стороне сервера
- •Принципы создания программ на сервере
- •Серверные программы, не соответствующие основным принципам разработки
- •Использование архитектуры Model!
- •Использование архитектуры на базе компонентов
- •Архитектуры, ориентированные на использование Web-служб
- •Частные решения: обмен данными
- •Взаимодействие, затрагивающее только клиентскую программу
- •Пример отображения информации о планетах
- •Взаимодействие, ориентированное на содержимое
- •Взаимодействие, ориентированное на сценарий
- •Передача данных серверу
- •Использование HTML-форм
- •Использование объекта XMLHttpRequest
- •Управление обновлением модели
- •Резюме
- •Ресурсы
- •Создание качественного приложения
- •Отклик программы
- •Надежность
- •Согласованность
- •Простота
- •Как получить результат
- •Предоставление сведений пользователю
- •Поддержка ответов на собственные запросы
- •Обработка обновлений, выполненных другими пользователями
- •Создание системы оповещения
- •Основные принципы оповещения
- •Реализация базовых средств оповещения
- •Отображение пиктограмм в строке состояния
- •Отображение подробных сообщений
- •Формирование готовой системы
- •Предоставление информации в запросах
- •Информация о новизне данных
- •Простой способ выделения данных
- •Выделение данных с использованием библиотеки Scriptaculous
- •Резюме
- •Ресурсы
- •JavaScript и защита браузера
- •Политика "сервера-источника"
- •Особенности выполнения сценариев в Ajax-приложении
- •Проблемы с поддоменами
- •Взаимодействие с удаленным сервером
- •Взаимодействие с Web-службами
- •Защита конфиденциальной информации
- •Вмешательство в процесс передачи данных
- •Организация защищенного НТТР-взаимодействия
- •Передача шифрованных данных в ходе обычного HTTP-взаимодействия
- •Управление доступом к потокам данных Ajax
- •Создание защищенных программ на уровне сервера
- •Ограничение доступа к данным из Web
- •Резюме
- •Ресурсы
- •Что такое производительность
- •Скорость выполнения JavaScript-программ
- •Определение времени выполнения приложения
- •Использование профилировщика Venkman
- •Оптимизация скорости выполнения Ajax-приложения
- •Использование памяти JavaScript-кодом
- •Борьба с утечкой памяти
- •Особенности управления памятью в приложениях Ajax
- •Разработка с учетом производительности
- •Простой пример управления памятью
- •Как уменьшить объем используемой памяти в 150 раз
- •Резюме
- •Ресурсы
- •Сценарий двойной комбинации
- •Недостатки клиентского решения
- •Недостатки клиентского решения
- •Архитектура клиента
- •Разработка взаимодействия клиент/сервер
- •Реализация сервера: VB.NET
- •Написание кода сервера
- •Представление результатов
- •Применение каскадных таблиц стилей
- •Дополнительные вопросы
- •Запросы при выборе нескольких элементов
- •Переход от двойного связного выбора к тройному
- •Реструктуризация
- •Новый и улучшенный объект netContentLoader
- •Создание компонента двойного списка
- •Резюме
- •Глава 10. Опережающий ввод
- •Изучаем опережающий ввод
- •Типичные элементы приложений опережающего ввода
- •Google Suggest
- •Ajax как средство опережающего ввода
- •Структура серверной части сценария: С#
- •Сервер и база данных
- •Тестирование серверного кода
- •Структура клиентской части сценария
- •HTML
- •JavaScript
- •Обращение к серверу
- •Дополнительные возможности
- •Реструктуризация
- •День 1: план разработки компонента TextSuggest
- •День 3: включаем Ajax
- •День 4: обработка событий
- •День 5: пользовательский интерфейс всплывающего окна с предлагаемыми вариантами
- •Итоги
- •Резюме
- •Эволюционирующий портал
- •Классический портал
- •Портал с богатым пользовательским интерфейсом
- •Создание портала с использованием Java
- •Таблица пользователя
- •Серверная часть кода регистрации: Java
- •Структура регистрации (клиентская часть)
- •Реализация окон DHTML
- •База данных окон портала
- •Серверный код окна портала
- •Добавление внешней библиотеки JavaScript
- •Возможность автоматического сохранения
- •Адаптация библиотеки
- •Автоматическая запись информации в базе данных
- •Реструктуризация
- •Определение конструктора
- •Адаптация библиотеки AjaxWindows.js
- •Задание команд портала
- •Выводы
- •Резюме
- •Понимание технологий поиска
- •Классический поиск
- •"Живой" поиск с использованием Ajax и XSLT
- •Возврат результатов клиенту
- •Код клиентской части сценария
- •Настройка клиента
- •Инициализация процесса
- •Код серверной части приложения: РНР
- •Создание XML-документа
- •Создание документа XSLT
- •Объединение документов XSL и XML
- •Совместимость с браузером Microsoft Internet Explorer
- •Совместимость с браузерами Mozilla
- •Последние штрихи
- •Применение каскадных таблиц стилей
- •Улучшение поиска
- •Поддержка браузерами Opera и Safari
- •Использовать ли XSLT
- •Решение проблемы закладок
- •Реструктуризация
- •Объект XSLTHelper
- •Компонент "живого" поиска
- •Выводы
- •Резюме
- •Считывание информации из внешнего мира
- •Поиск XML-лент
- •Изучение структуры RSS
- •Богатый пользовательский интерфейс
- •Чтение лент
- •HTML-структура без таблиц
- •Гибкое CSS-форматироеание
- •Глобальный уровень
- •Предварительная загрузка средствами Ajax
- •Богатый эффект перехода
- •Правила прозрачности, учитывающие индивидуальность браузеров
- •Реализация затухающего перехода
- •Интеграция таймеров JavaScript
- •Дополнительные возможности
- •Введение дополнительных лент
- •Интеграция функций пропуска и паузы
- •Как избежать ограничений проекта
- •Обход системы безопасности браузеров Mozilla
- •Изменение масштаба приложения
- •Реструктуризация
- •Модель приложения
- •Представление приложения
- •Контроллер приложения
- •Выводы
- •Резюме
- •Отладчики
- •Для чего нужен отладчик
- •Средство Safari DOM Inspector для Mac OS X
- •Ресурсы
- •JavaScript — это не Java
- •Формирование объектов
Глава 12. "Живой" поиск с использованием XSLT 485
Цикла DOM XML на стороне клиента можно избежать, если перед отправкой клиенту сформировать на сервере вместо XML-файла таблицу HTML. Используя такую технологию, мы соединяем дескрипторы HTML в большую строку, подобно тому, как мы формировали XML-документ. Однако теперь вместо дескрипторов XML применяются элементы таблицы. Строка HTML-кода возвращается клиенту, где ее можно присвоить свойству innerHTML элемента. В данном случае использцется свойство responseText объекта XMLHttpRequest, поскольку нам не требуется проходить по узлам.
Недостаток описанной технологии заключается в том, что мы должны динамически обработать данные и создать таблицу (либо на стороне сервера, либо на стороне клиента). Если в будущем потребуется изменить формат таблицы, то в зависимости от сложности таблицы это может оказаться проблематичным. Добавление или удаление столбца может представлять проблему, поскольку мы должны будем изменить код внутри цикла. Кроме того, следует учесть, что в нашей строке содержатся кавычки; необходимо убедиться, что при создании строки они были представлены правильными управляющими последовательностями. Кроме того, если мы введем JavaScript-код в дескриптор HTML, то получим еще больше двойных и одинарных кавычек, с которыми нужно что-то делать, — необходимо проверить, что все дескрипторы правильно отформатированы и закрыты. Единственная возможность сделать все это — изучить текст после создания строки.
Чтобы избежать данных проблем, мы можем использовать XSLT. Применяя инфраструктуру Ajax, можно объединить XSLT-файл с XMLдокументом и отобразить результаты, не прибегая к использованию методов DOM. Если разработчик знает XSLT, но не является асом в использовании JavaScript, данное решение может быть превосходным.
Обсуждая поиск Ajax, следует отметить, что он не требует дообработки на сервере, следовательно, URL страницы не изменяется, чтобы соответствовать результатам поиска. Таким образом, создавая закладку на URL, мы не получим требуемых результатов поиска. В классических приложениях поиска, подобных Google, мы можем легко копировать URL со страницы, сформированной при поиске, вставить его в электронное письмо, и когда получатель щелкнет на такой ссылке, он увидит искомые результаты. Однако при Ajaxпоиске такую возможность необходимо закодировать отдельно. Подробности этого процесса рассмотрены в разделе 12.5.4.
12.2. Код клиентской части сценария
Технология форматирования XML-данных с использованием XSLT довольно популярна, поскольку XML-файл обладает структурой, легко поддающейся обработке. В предыдущих проектах (например, в приложении опережающего ввода, рассмотренном в главе 10) мы использовали JavaScript, XML и DOM для создания отображаемого HTML-кода. В данном примере для получения того же эффекта мы будем использовать XSLT.
XSLT позволяет форматировать данные, формируя структуру HTML в другом файле и объединяя его с документом XML. Файл XSLT отвечает
486 Часть IV Ajax в примерах
за все, кроме навигации по узлам XML и построения таблиц, меню и HTMLструктуры. Используя Ajax, мы можем извлечь статический или динамический файл XML и статический или динамический файл XLST с сервера, объединив их на стороне клиента для создания HTML-доку мента. Всю работу с XSLT можно выполнить и на стороне сервера, но мы будем рассматривать преобразования на стороне клиента.
12.2.1. Настройка клиента
В данном проекте мы рассмотрим поиск в телефонной книге по имени пользователя. Для этого используется одно текстовое окно и одна кнопка Отправить. Форма поиска показана в листинге 12.1.
Листинг 12.1. Форма клиентской части приложения
<form name="Forml" ID="Forml" onsubmit="GrabNumber();return false;">
// О Добавить обработчик onsubmit
Name: <input name="user" type="text"/> // 0 Вставить текстовое окно
<input type="submit" name="btnSearch" value="Search" />
//© Добавить кнопку отправки <br/Xbr/>
<div id="results"></div>
//О Добавить элемент d i v для результатов </form>
Для инициализации "живого" поиска к дескриптору form необходимо добавить обработчик событий. Обработчик событий onsubmit О перехватывает нажатие клавиши <Enter>, если указатель мыши расположен в текстовом окне, а пользователь щелкает на кнопке Отправить. Данный обработчик событий вызывает функцию GrabNumber(), инициирующую XMLHttpRequest без возврата формы на страницу. (В реальной ситуации необходимо проверить, не отключил ли пользователь JavaScript. В таком случае форма будет отправляться на сервер, и для поддержки подобных пользователей можно использовать классическую форму поиска. Впрочем, в данном проекте мы такую возможность не рассматриваем.)
Созданная нами форма является базовым вариантом, содержащим только обработчик событий, инициирующий XMLHttpRequest. Для сбора пользовательских критериев поиска к форме добавлены текстовое окно © и кнопка Отправить ©. Если мы хотим чего-то необычного, к текстовому окну можно еще добавить обработчик событий onblur, вызывающий функцию GrabNumЬег (); в таком случае поиск будет запущен тогда, когда текстовое окно перестает находиться в фокусе В данном примере активизация поиска связана с обработчиком событий onsubmit.
Затем в документ добавляется элемент div О, в который будут выводиться результаты поиска. Его можно разместить в любом месте станицы. в котором мы желаем видеть результаты. К div добавляется идентифика-
Глава 12 "Живой" поиск с использованием XSLT 487
тор, поэтому мы можем ссылаться на этот элемент при добавлении результатов и GIF-анимации. Отметим, что использовать данный элемент для вывода результатов не обязательно. Их можно выводить в ячейку таблицы или даже в элемент span. Фактически можно использовать любой элемент HTML, свойством innerHTML которого мы можем манипулировать. Мы выбрали элемент div потому, что это блочный элемент, содержащий разрыв строки перед началом и после конца элемента. Кроме того, div занимает 100% доступной ширины браузера, из-за чего он больше подходит для выдачи пользователю больших таблиц результатов.
Важно отметить, что обработчик событий onsubmit должен возвращать значение false при выполнении обработчика. Это уведомляет браузер, что форму не нужно отправлять на сервер, что инициировало бы обновление всей страницы и прервало бы JavaScript-программу формы. Обработка возвращаемого значения приведена в листинге 12.2.
12.2.2. Инициализация процесса
В данном примере мы используем на сервере два файла: документ XML и документ XSL. Документ XML динамически создается РНР, когда этого требует клиент. PHP-код принимает то, что пользователь ввел на страницу, инициирует запрос к базе данных, а затем форматирует результаты в виде XML-документа. Статический документ XSL превращает наш динамический XML-файл в документ HTML. Поскольку документ XSL статический, его не требуется создавать серверу в момент клиентского запроса, это можно сделать заблаговременно.
Точно так же, как и в других проектах, рассмотренных в данной книге, для инициализации объекта XMLHttpRequest мы используем отдельную функцию. Процесс сбора необходимой информации и вызов функции представлен в листинге 12.2.
ЦЦистинг 12.2. Функция инициализации 'ШШЩШШШШШ1ШШШ function GrabNumber(){
// Создать функцию
v a r urlXML='PhoneXML.php?q=' + d o c u m e n t . F o r m l . u s e r . v a l u e ;
//О Сформировать URL XML
va r urlXSL=•Phone.xsl' ;
//© Сформировать URL XSL
va r newlmg=document . createElement('img' ) ;
//© Создать элемент изображения
n e w l m g . s e t A t t r i b u t e ( ' s r c ' , ' i m a g e s / l o a d i n g . g i f ) ; // О Установить источник
d o c u m e n t . g e t E l e m e n t B y I d ( " r e s u l t s " ) . a p p e n d C h i l d ( n e w l m g ) ;
//© Добавить изображение на страницу LoadXMLXSLTDoc{urlXML,urlXSL,"results");
//0 Начать загрузку
Данная функция собирает информацию, требуемую для вызова сервера, устанавливает изображение, которое будет отображаться в процессе обра-