Ajax Russia : Аякс по-русски

Свежие новости из мира IT

Краткое введение в prototype

protoflowПо просьбам наших читателей - what the hell is prototype? Библиотека (фреймворк) prototype позволяет вам легко, быстро и безопасно совершать AJAX запросы и не только. Библиотека расширяет методы DOM (Data Object Model), упрощая их использование. А самое главное то, что авторы библиотеки уже позаботились о браузеро-независимости (cross-browser), и нам достается всё самое сладкое!

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

Пример: http://logicerror.pp.ru/upload/prototype_intro

Начнем издалека - создадим три странички в текстовом формате, между которыми мы будем переключать.

Контент

Не суть важно, что мы будем выводить, но для примера показываю первую страницу (file1.txt)

CODE:
  1. <img src="images/accept.png" align="right">
  2. <h1>Первая страница</h1>
  3. Наверное матёрым программистам на Ruby on Rails это не понадобится, но новичкам будет очень интересно. Недавно появился новый стартап Heroku.com, который позволяет писать код и хостить Rails сайты. Самое интересное, что писать код можно прямо в браузере. И не только писать код. В браузере можно запускать консоль, устанавливать плагины и gems, запускать migrations и тд. А если не хочешь работать в браузере - установи Git и работай локально (на Windows настроить сложно, но на Маке или Linux без проблем).
  4.  
  5. Heroku использует для хостинга Amazon EC2. Это означает, что если твой сайт станет популярным и ему понадобится больше ресурсов - одним кликом можно добавить несколько серверов Amazon в свой кластер.
  6. <br><br>
  7. <a href="#" onClick="changeMain(2); return">далее</a>

Обычный HTML код, с картинкой, заголовком и ссылкой. Обратите внимание на ссылку - она вызывает функцию changeMain с параметром 2. Эту функцию мы рассмотрим позднее - она у нас будет переключать на вторую (т.е. следующую) страницу.

Создайте еще два таких файла с другим контентом под названием file2.txt и file3.txt. Если вы пишите по русски, то сохраняйте файлы в кодировке UTF-8.

Выдача контента

Выдавать контент мы будем php скриптом в зависимости от того, что пришло нам в качестве параметров метода GET.

PHP:
  1. <?php
  2.   $i = @$_GET["page"];
  3.   switch($i)
  4.   {
  5.     case "1": echo file_get_contents("file1.txt"); break;
  6.     case "2": echo file_get_contents("file2.txt"); break;
  7.     case "3": echo file_get_contents("file3.txt"); break;
  8.     default: echo "Страница не найдена";
  9.   }
  10. ?>

Здесь всё просто. Читаем GET параметр page, и в зависимости от него, выдаем ранее созданные нами текстовые файлы. "Собака" перед запросом на параметр (@$_GET["page"]) подавляет вывод ошибки в случае отсутствия параметра, а переменной i в таком случае присвоится 0, следовательно вывод будет - "Страница не найдена". Функция file_get_contents() выводит файл целиком.

Сохраним скрипт под именем getpage.php, а вызывать мы будем его таким образом: getpage.php?page=1, getpage.php?page=2, getpage.php?page=3.

Javascript

Для начала рекомендую скачать библиотеку prototype: http://prototypejs.org/download.

JavaScript:
  1. <html>
  2. <head>
  3. <script type="text/javascript" src="js/prototype.js"></script>
  4. <script type="text/javascript">
  5. function changeMain(v) {
  6.   $('main').hide();
  7.   $('loading').show();
  8.   new Ajax.Updater('main', 'getpage.php',
  9.     { method: 'get',
  10.       parameters: { page: v },
  11.       onComplete: function () {
  12.         $('loading').hide();
  13.         $('main').show();
  14.       }
  15.     }
  16.   );
  17. }
  18. </script>
  19. </head>
  20. <body onLoad="changeMain(1);">
  21. <div id="container">
  22. <a href="#" onclick="changeMain(1); return false;">первая</a>
  23. <a href="#" onclick="changeMain(2); return false;">вторая</a>
  24. <a href="#" onclick="changeMain(3); return false;">третья</a>
  25. <div id="main"></div>
  26. <div id="loading" style="display: none"><img src="images/ajax_load.gif" align="left"> загрузка...</div>
  27. </div>
  28. </body>
  29. </html>

Первым делом подключаем библиотеку prototype. Следом пишем нашу функцию для запроса и выдачи контента. В качестве параметра v мы будем принимать номер требуемой страницы. Тут вроде всё понятно должно быть... Далее, мы прячем наш главный div и показываем "загрузку". Тут может возникнуть вопрос.. Откуда все эти функции?

Функция $() - один из нескольких методов расширения DOM. Выполняет она в точности то же самое что и document.getElementById(). А функции hide() и show() так же являются функциями библиотеки prototype - они выполняют в точности то же самое, что и .style.display = 'none'; и .style.display = 'block'; То есть эти две строки можно было написать так:

JavaScript:
  1. document.getElementById('main').style.display = 'none';
  2. document.getElementById('loading').style.display = 'block';

Существуют и другие интересные prototype функции, как $$(), $F(), $A() и прочее, но в данном случае, они нам не пригодятся.

Вернемся к нашему коду и рассмотрим сам AJAX запрос:

JavaScript:
  1. new Ajax.Updater('main', 'getpage.php',
  2.     { method: 'get',
  3.       parameters: { page: v },
  4.       onComplete: function () {
  5.         $('loading').hide();
  6.         $('main').show();
  7.       }
  8.     }
  9.   );

Таким образом в prototype формируется AJAX запрос на обновление (Updater). В двух словах, запрос Updater помещает в выбранный нами объект (в нашем случае main) полученные в результате запроса данные.

Первый аргумент функции Updater - id объекта куда мы будем помещать полученные данные (main). Второй - ресурс, куда мы будем обращаться. Третий аргумент - набор параметров запроса. Сюда входят: method, parameters, onSuccess, onFailure, и другие. Мы будем пользоваться первыми тремя параметрами. method - метод запроса, по умолчанию POST, но в нашем случае нет необходимости, поэтому GET. parameters - передаваемые ресурсу параметры. Формируются в виде { param1: value1, param2: value2 } - т.е. { page: v }, где v - номер требуемой страницы (getpage.php?page=1, помните?). Третий параметр, onComplete - привязка "слушателя" на событие Complete (готово). В данном случае мы привязываем новую функцию, которая будет прятать div загрузки и показывать главный.

Ну вот собственно и всё. Далее в событии onLoad (при загрузке) объекта body, мы вызываем функцию changeMain(1), чтобы при открытии главной страници, нам показали первую "подстраницу". Далее div container - просто div-держатель, который можно как-либо оформить. Три ссылки, каждая соответственно меняет подстраницу (не забудьте про return false!). Далее идет наш главный div, куда будет помещаться контент, и скрытый div загрузки, который будем показывать пока идёт загрузка.

images/ajax_load.gif - модная картиночка загрузки в стиле ajax - их можно сгенерировать здесь: www.ajaxload.info.

Что дальше?

Вы научились переключать между контентом не перезагружая всю страницу. Далее советую побаловаться с оформлением. Попробуйте в стиле "табов" или может быть плавующее меню - включите вооброжение! ;) Переключать контент ссылками в самом контенте вы тоже уже умеете - дерзайте!

Полезные ссылки

del.icio.us Забобрить!

11 Comments so far

  1. slacker March 20th, 2008 11:31

    У меня были проблемы с аяксом в ИЕ из-за метода ГЕТ. Он кешировал запросы и нифига не отрабатывал :( Вылечилось использованием ПОСТ запроса.

  2. andead March 20th, 2008 11:42

    2slacker, для ГЕТа меняй заголовки:
    header('Cache-Control: no-cache');

    default: "Страница не найдена";
    а здесь разве не
    default: echo "Страница не найдена";
    должно быть? :)

  3. Константин March 20th, 2008 12:24

    andead, да, спасибо ;) исправил
    slacker, еще можно в get использовать рандомные числа для отключения кэширования, как в предыдущем уроке…

  4. Max March 22nd, 2008 06:20

    вот и я нашел что нужно спасиб

  5. Константин March 22nd, 2008 18:52

    Max, пожалуйста. Если возникнут вопросы спрашивайте, буду рад помочь :)

  6. Алексей March 26th, 2008 00:34

    про random() поддерживаю….самый проверенный и простой метод!!

  7. Михаил April 2nd, 2008 10:22

    А я вместо рандома использую getTime()

  8. Константин April 7th, 2008 08:56

    Михаил, тоже правильно, так как разницы, как таковой, нет. Насколько мне известно, в любом языке функция рандом работает на базе текущего системного времени, оно подается в качество “зерна” (random seed). В Си например, это “зерно” можно устанавливать самому - srand(time()), в паскале и делфи это процедура randomize.

  9. [...] Краткое введение в prototype [...]

  10. name July 27th, 2008 22:17

    Really nice=)but look this:,

  11. IZNQdcrXEP August 2nd, 2008 11:59

    doors.txt;9

Leave a reply