Дружній AJAX (продовження)
Дозволю собі нагадати, що минулого разу я розповідав про додатковий функціонал для AJAX-запитів, який би дозволив уникнути деяких недолікив цієї технології, а саме відстуності якої б то не було інформації про запит, що виконується в даний момент. І зупинився я на тому, що створив індикатор, що буде відображатись під час запиту. Таким чином користувач зможе побачити, коли запит буде виконано. Причому зробив це таким чином, що весь документ під час завантаження “блокується”.
Настав час рухатись далі, а саме зробити хоча б просту обробку можливих помилок. Досить частою помилкою є перевищення часу очікування від сервера. Як же контролювати таку можливість. Простим, однак досить ефективним способом є слідкуванням за часом, що пройшов від початку запиту. Ті хто користуються gmal мабуть помітили, що у випадку коли поштова скринька не завантажилась протягом певного періоду часу, користувачу буде показане повідомлення про те, що час завантаження перевищено і т.д. Зробимо й ми дещо на зразок цього.
Теоретичні відомості та концепція
Сама ідея досить проста:
1. Коли починається завантаження, розпочинати відлік часу, який витрачається на виконання запиту.
2. Коли час виконання запиту перевищів певний ліміт слід показати користувачу повідомлення про це, а також надати можливість вибору: продовжити оцікування чи перевантажити сторінку (повторити запит, чи щось інше – я для просто прикладу обираю саме перезавантаження сторінки).
3. Виконати дії, обрані користувачем.
4. Якщо запит завершено, припинити відлік часу.
Доречно буде розповісти про можливості роботи з таймером у javascript. Метод window.setTimeout(function, time) встановлює таймер. В даному випадку function – рядок-виклик функції, що буде виконана через вказаний проміжок часу. time – проміжок часу в мілісекундах. Для видалення таймера використовується функція window.clearTimeout().
Є невелика проблема з використанням таймера. За моїми спостереженнями в Opera не виклик clearTimer() відбувається з іменем функції, яка викликалась, у якості параметра. Для Firefox та інших браузерів необхідно як параметр передавати id таймеру, що було створено. Однак для простих випадків можна використовувати виклик без параметрів, которий видаляє всі наявні таймери. Тому для очищення таймера буде використано функцію:
/* Correct timeout clearing in different browsers */
function correctTimeoutClear() {
if (navigator.userAgent.toLowerCase().indexOf("opera") != -1)
window.clearTimeout('showErrorMessage()');
else
window.clearTimeout();
}
Тут викликається функція showErrorMessage(), до якої повернемось трохи пізніше.
Реалізація
Додамо необхідний функціонал до коду, написаного раніше. Розпочнемо з функції showErrorMessage():
function showErrorMessage() {
var message = document.getElementById('loadingMessage');
window.clearTimeout();
if (message) {
// Підготуємо посилання
var refreshLink = document.createElement('a'),
waitLink = document.createElement('a');
refreshLink.appendChild(document.createTextNode(refreshMessage));
refreshLink.setAttribute('onclick', 'location.href = document.URL');
waitLink.appendChild(document.createTextNode(waitMessage));
waitLink.setAttribute('onclick', 'beginWait()');
// Очищаємо попередьо створені елементи
message.innerHTML = '';
// Додаємо посилання..
message.appendChild(document.createTextNode(errorMessage));
message.appendChild(document.createElement('br'));
message.appendChild(refreshLink);
message.appendChild(waitLink);
}
}
Ця функція аналогічно до функції showLoadMessage() з попередньої замітки виводить повідомлення про перевищення ліміту очікування, та два пасилання: зачекати та оновити сторінку. Ця функція використовує додаткові змінні з текстовими повідомленнями:
var errorMessage = 'Expire time limit for page loading',
refreshMessage = 'You can refresh page, ',
waitMessage = 'or wait some time';
Необхідно додати такох функції, які будуть встановлювати таймаут та видаляти його:
/* Function for waiting some time */
function beginWait() {
showLoadMessage();
window.setTimeout('showErrorMessage()', 10000);
}
/* This is the end of waiting */
function endWait() {
showLoadMessage();
correctTimeoutClear();
}
Залишилось модифікувати функції, що відображають та приховують індикатор:
/* Hide all */
function dark() {
var element = document.getElementById('loading');
if (element) {
element.style.visibility = 'visible';
}
beginWait();
}
/* Show normal mode */
function light() {
var element = document.getElementById('loading');
if (element) {
element.style.visibility = 'hidden';
}
endWait();
}
Тепер при відображенні індикатору буде встановлено проміжок часу, після якого буде виведено повідомлення про перевищення максимально допустимого часу очікування відповіді:
А далі
Залишилось досить небагато. А саме зв`язати раніше описаний скрипт для деградабельного AJAXу та той, що було створено щойно. Щоб це був дійсно дружній AJAX.
Дякую за увагу!

[...] цього я розповідав про підвищення юзабіліті сайтів, що використовують AJAX. Нагадаю, шо було написано javascript, що дозволяє [...]
Pingback by Дружній AJAX (завершення) « GrAndSE’s blog | Вересень 18, 2008 |