http://blagtalkan.ru
http://oktpoisk.ru
http://mysorru.ru/
http://san-okt.ru/
http://pes6evolution.ru/
http://chasikigov.ru
http://serafimsovet.ru
http://filmsgov.ru
http://free-domen.ru
http://fithonda.ru/forums/index.php
http://avtogov.ru
http://www.1001bilet.com.ua/base/on-line/
http://pravilavoini.ru
http://school41ufa.ru
http://rusrav4.ru
Пример предварительной загрузки страницы | Книга AJAX
 

Вы уже знаете, что один из самых простых и логичных случаев приме¬нения шаблона выборки данных с предсказанием - это предваритель¬ная загрузка страниц статьи. С появлением сетевых дневников, или блогов, похоже, что каждый заразился стремлением написать статью и выложить ее на своем собственном сайте. Чтение длинных статей -занятие достаточно утомительное, поэтому чаще всего их разбивают не несколько страниц. Читать отдельные страницы не так утомитель¬но, но это приводит к увеличению общего времени загрузки, потому что с каждой новой страницей повторно загружаются информация о форматировании, различных меню, а также рекламные баннеры, унаследованные с первой страницы. Шаблон выборки данных с пред¬сказанием облегчает загрузку информации как для клиента, так и для сервера, поскольку загружается только текст следующей страницы, пока пользователь занят чтением предыдущей.
Для начала необходимо создать страницу, которая будет включать в се¬бя логику шаблона выборки данных с предсказанием на стороне серве¬ра. Отображением статьи на стороне сервера будет заниматься сцена¬рий ArticleExample.php:
<?php
$page = 1; SdataOnly =.false;
(isset($_GET["page"])) {
$page = (int) $_GET["page"];

;
По умолчанию этот сценарий отображает первую страницу с текст статьи. Если в строке запроса указывается номер страницы, наприм раде=2, то отображается страница с заданным номером. Если в строкезапроса содержится параметр dataonly=true, то клиенту передается только элемент , содержащий текст статьи на заданной страни¬це. В комбинации с параметром page это позволяет запрашивать толь¬ко текст любой из страниц.
HTML-код страницы включает место под заголовок статьи, а также элемент , используемый для загрузки дополнительной страни¬цы. В этом элементе атрибут display имеет значение попе, т. е. его содержимое не будет отображаться. Код сценария на языке РНР выводит помимо прочего список страниц статьи. В данном примере статья будет состоять из трех страниц, поэтому сценарий выводит три ссылки вверху страницы (рис. 3.1).
Номеру текущей страницы назначается класс CSS current, чтобы поль¬зователь видел, какую страницу он просматривает. Этот класс описан в файле Article, ess:
a.current { color: black; font-weight: bold; text-decoration: none;

Когда пользователь просматривает страницу, ссылка на нее выводится жирным шрифтом черного цвета без подчеркивания, что однозначно определяет номер просматриваемой страницы. По умолчанию эти ссылки просто обращаются на ту же самую веб-страницу, изменяется только значение параметра page в строке запроса - именно так на большинстве сайтов организуется доступ к отдельным страницам статей. Однако применение шаблона выборки данных с предсказанием позво ляет повысить скорость доступа к данным и тем самым улучшить ощу¬щения пользователя от работы с сайтом.
В данном примере для реализации шаблона выборки данных с пред¬сказанием необходимо определить несколько глобальных переменив JavaScript:
var oXmlHttp = null;: var iPageCount: J var iCurPage = -1; > var iwaitBeforeload =
5000;
var iNextPageToLoad = -1;
// Объект XMLHttp
// Количество страниц
// Номер текущей страницы
// Время (е мс) перед загрузкой
// очередной страницы
// Номер следующей загружаемой страницы

Первая переменная - это объект XMLHttp, посредством которого буи производиться запросы на получение дополнительной информация Вторая переменная, iPageCount, содержит количество страниц в стать (Здесь мы жестко задали число страниц, но на практике оно обычно i нерируется динамически.) В переменной iCurPage хранится номер кущей страницы, просматриваемой пользователем. Следующие дв переменные непосредственно связаны с алгоритмом предварительно загрузки данных: iWaitBeforeLoad - это количество миллисекунд, кот рые должны пройти, прежде чем можно будет приступить к загрузи очередной страницы, a iNextPageToLoad - это номер страницы, котора должна быть загружена через заданный промежуток времени. В эч примере новая страница загружается в фоновом режиме через 5 кунд (5000 миллисекунд), чего вполне достаточно, чтобы дать поль вателю прочитать несколько первых предложений и решить - сто§ ли читать статью дальше. Если пользователь читает статью долы 5 секунд, то есть вероятность, что он захочет прочитать ее и до конт.
Прежде всего вам понадобится функция, которая будет возвращая URL конкретной страницы. Эта функция называется getURLForPageO Она принимает единственный аргумент, определяющий номер требу мой страницы, и извлекает URL текущей страницы, дополняя ея строкой запроса с параметром page:

function getURLForPage(iPage) { var sNewUrl = location.href; if (location.search.length > 0) { sNewUrl - sNewurl.substring^,'
}
sNewUrl += "?page=" + iPage; . return sNewUrl;
Текущий URL извлекается из location.href, который содержит пол¬ный URL страницы, включая строку запроса.1 Затем проверяется на¬личие строки запроса в URL. Если location, search, length имеет значе¬ние больше нуля (функция location, search возвращает строку запроса, если таковая вообще существует, включая знак вопроса), то строка за¬проса существует, и она удаляется из URL с помощью метода sub-string(). Затем к URL добавляется новый параметр page и полученный URL возвращается как результат работы функции. Такая функция может вам пригодиться во множестве ситуаций.
Следующая функция по имени showPage() (как вы уже наверняка дога¬дались по ее имени) отвечает за отображение следующей страницы статьи:
function showPage(sPage) { ;
var divPage = document.getElementById("divPage" + sPage);
if (divPage) { • -
for (var i=0; i < iPageCount; i++) { var iPageNum = i+1;
var divOtherPage = document.getEleraentById("divPage" + iPageNum); var aOtherLink = document.getElementByldC'aPage" + iPageNum); if (divOtherPage && sPage != iPageNum) {
divOtherPage.style.display = "none";
aOtherLink.className = "";
divPage.style.display = "block";
document.getElementByldC'aPage" + sPage).className = "current"; } else {
location.href = getURLForPage(parseInt(sPage));
Эта функция сначала проверяет, была ли ранее загружена требуемая страница в элемент . Если была, то элемент будет иметь идентификатор divPage плюс номер страницы (например, divPagel -для первой страницы, divPage2 - для второй и т. д). Если этот элемент существует, значит, страница была предварительно загружена, и, таким образом, можно просто переключиться на нее. Для этого в цикле выполняется обход всех страниц, и те из них, которые не соот¬ветствуют аргументу sPage, делаются невидимыми. Одновременно с этим в ссылках на страницы вместо имени класса CSS подставляется пустая строка. Затем в элементе с текущей страницей в атрибут display записывается значение block, чтобы сделать его видимым, и ссылке на эту страницу назначается класс CSS current.Если же искомый элемент не был найден, то переход на очере ную страницу статьи осуществляется старым добрым способом: опред ляется адрес перехода (с помощью функции getURLForPage(), описанно ранее), который и записывается в location, href. Этот запасной вариа предусмотрен на тот случай, если пользователь щелкнет по ссылке номером страницы еще до того, как истекут 5 секунд.
Загрузка очередной страницы выполняется с помощью функции load NextPage(). Эта функция запрашивает очередную страницу только в то-случае, если номер страницы находится в допустимых пределах:
Функция начинается с проверки номера страницы, хранящегося в п ременной iNextPageToLoad, путем сравнения его со значением переме ной iPageCount. Если этот тест благополучно пройден, то далее провер ется, был ли создан объект XMLHttp. Если нет, то он создается с пом щью метода createRequest() библиотеки zXml. Если он уже создан, гда проверяется свойство readyState на равенство 0. Если свойс readyState не равно нулю, необходимо вызвать метод abortQ, чтоб прервать исполнение предыдущего исполняющегося запроса.
Затем вызывается метод ореп(), которому сообщается, что запрос буд асинхронным запросом GET. Далее вызывается функция getURLFor Page() для определения URL страницы, к которому в конец дописы ется строка "&dataonly=true", указывающая, что запрашивается толь, текст страницы статьи. Теперь рассмотрим обработчик события on re dystatechange.
В этом примере обработчик события on readystatechange отвечает за пр ем текста статьи и создание соответствующей структуры DOM:
function loadNextPage() {
if (iNextPageToLoad <= iPageCount) {
if (!oXmlHttp) {
oXmlHttp = zXmlHttp.createRequestO; } else if (oXmlHttp.readyState != 0) {
oXmlHttp. abortO;
}
oXmlHttp.open("get", getURLForPage(iNextPageToLoad)
+ "&dataonly=true", true); oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) { if (oXmlHttp.status == 200) {
var divLoadArea = document.getElementById("divLoadArea");
divLoadArea.innerHTML - oXmlHttp.responseText;
var divNewPage = document.getElementByld("divPage"
1;9>-^ 7 . .,+ iNextPageToLoad);
divNewPage.style.display = '.'none"; document.body.appendChild(divNewPage); divLoadArea.innerHTML = ""; iNextPageToLoad++; ;: setTiroeout(loadNextPage, iWaitBefоreLoad);
Как уже говорилось в предыдущей главе, свойство readyState проверя¬ется на равенство числу 4 (запрос выполнен), а затем, чтобы убедиться • безошибочном выполнении запроса, свойство status проверяется на равенство числу 200. Если эти два условия выполнены, начинается фактическая обработка. Для начала функция получает ссылку на эле¬мент , в который загружается страница, и сохраняет ее в нере¬шенной divLoadArea. Затем содержимое свойства responseText запроса переносится в свойство innerHTML элемента . Текст ответа пред¬ставляет собой фрагмент кода HTML, поэтому он будет проанализиро-: броузером, что, в свою очередь, приведет к созданию соответствую-: объектов DOM. Далее функция получает ссылку на элемент , куда была записана только что полученная страница (мы уже знаем, что атрибут id элемента представляет собой сочетание слова divPage ж номера страницы, который хранится в переменной iNextPageToLoad), а его атрибуту display присваивается значение попе, чтобы страница осталась невидимой при перемещении за пределы области загрузки. Следующая строка добавляет элемент divNewPage в тело документа, по¬мещая его в область просмотра для дальнейшего использования. По¬сле этого свойство innerHTML области загрузки очищается и подготавли¬вается к загрузке другой страницы. В заключение наращивается значение переменной iNextPageToLoad и устанавливается тайм-аут, по чении которого функция будет вызвана вновь. Эта функция б вызываться каждые 5 секунд, пока все страницы не будут загру:
Поскольку эта страница может работать и без кода JavaScript, этот код присоединяется к странице во время исполнения, после как сценарий убедится, что броузер поддерживает объект XML -К счастью, объект zXmlHttp из библиотеки zXml имеет функцию 1 ported(), которая может применяться для этой цели:
window.onload = function () { if (zXmlHttp.isSupportedO) {
// здесь начинает работу код поддержки технологии Ajax

Этот блок, внутри которого размещается весь код, реализующий лон выборки данных с предсказанием, гарантирует, что броузер, имеющий поддержки XMLHttp, не будет оказывать отрицательное ние на работоспособность веб-приложения.
Прежде всего необходимо определить, какую страницу статьи в ящий момент времени читает пользователь. Для этого необходимо смотреть строку запроса в URL и определить, задан ли параметр Если да, то нам остается только извлечь из строки запроса номер ницы, в противном случае можно предположить, что номер тек страницы равен 1 (по умолчанию).
window.onload = function () { if (zXmlHttp.isSupportedO) {
if (location.href.indexOf("page=") > var sQueryString = location.search.substring(l); iCurPage = parseInt(sQueryString.substring(sQueryString.indexOf("=")♦ } else { iCurPage =1;

iNextPageToLoad = iCurPage+1;
// здесь располагается остальной код
}
};
В этом фрагменте кода выполняется поиск строки раде= в URL с цы (который доступен через location, href). Если она будет найде строка запроса извлекается из URL с помощью функции location. s (она возвращает только строку запроса, включая знак вопроса, рый отбрасывается с помощью вызова substring(l)). В след строке извлекается часть строки запроса, расположенная правее вола «=> (здесь должен находиться номер страницы), преобраз в целое число с помощью функции parselnt() и сохраняется в пе

нон iCurPage. Если же параметр page в строке запроса найден не будет, то предполагается, что текущий номер страницы равен 1, каковое зна¬чение и записывается в переменную iCurPage. В последней строке выде¬ленного фрагмента кода вычисляется номер следующей страницы (он на единицу больше текущего) и записывается в переменную iNextPage¬ToLoad, благодаря чему исключается возможность повторной загрузки уже доступных данных.
Второй шаг заключается в том, чтобы изменить функциональность ссылок на странице. По умолчанию эти ссылки обращаются к одному ж тому же сценарию на сервере, но с различными строками запроса, чтобы указать, какая страница была затребована. Если объект XMLHttp поддерживается броузером, то необходимо отменить поведение ссылок по умолчанию и заставить их обращаться к функциональным особен¬ностям Ajax:
window,onload = function () { if (zXralHttp.isSupportedO) {
if (location.href.indexOf("page=") > -1) {
var sQueryString = location.search.substrings); iCurPage = parselnt(
sQuerySt ring.subst ring(sQuerySt ring.indexOf("=")+1));
} else {
iCurPage = 1;
>
iNextPageToLoad = iCurPage+1;
var colLinks = document.getElementsByTagName("a"); for (var i=0; i < colLinks.length; i++) {
if (colLinks[i].id.indexOf("aPage") == 0) { colLinks[i].onclick = function (oEvent) { var sPage = this.id.substring(5); showPage(sPage);
if (oEvent) {
oEvent.preventDefault(); } else {
window.event.returnValue = false;
setTimeout(loadNextPage, iWaitBeforeLoad);
>
Здесь с помощью функции getElementsByTagName производится поиск ссылок (элементы <а />). Если атрибут id найденной ссылки начинает¬ся со строки аРаде, значит, это ссылка на страницу, и ее необходимо
преобразовать. Поиск строки выполняет функция indexOfO, возври щаемое значение которой проверяется на равенство 0, поскольку исет мая подстрока должна находиться только в самом начале строки. 3i тем ссылке назначается обработчик события onclick. Внутри этого о) работчика с помощью функции substringO номер страницы извлекая ся из атрибута id ссылки (this, id) и передается функции showPage . описанной ранее в этом же разделе и отображающей страницу. Остаа ся лишь отменить действие ссылки по умолчанию, т. е. переход на ш вую страницу. Из-за различий между Internet Explorer (IE) и модели событий в DOM дальнейший ход событий для IE и для DOM-совмесп мых броузеров отличается, для чего и необходим условный операта if. Если функции был передан объект event (аргумент oEvent), значш мы имеем дело с DOM-совместимым броузером и для того, чтобы отм нить действие по умолчанию, должны вызвать метод preventDefault' Но если в о Event было передано значение null, то сценарий исполняете под управлением IE, и объект event доступен как window, event. В эта случае мы должны записать в свойство returnValue этого объекта зва чение false, поскольку именно таким образом в IE отменяется дейа вие по умолчанию.
После обработки всех ссылок задается время тайм-аута, по истеченя которого будет запущена функция loadNextPageQ. Первый вызов это функции произойдет через 5 секунд и автоматически загрузит втору! страницу.
Проверяя работоспособность этого примера, попробуйте пощелкать о ссылкам в различные моменты времени. Так, если вы щелкнете i ссылке раньше, чем истечет пятисекундный интервал, вы обнаруж! те, что в результате изменилась строка запроса в URL. Подождав я сять секунд и щелкнув по ссылке, вы увидите, что текст изменяете! а строка URL нет (кроме того, вы должны заметить увеличение скор! сти загрузки новой страницы).