В последнее время участились вопросы «хочу сделать сайт на ajax», «как подгружать разделы через ajax» и тд.
Вообще, судя по всему, MODX настолько дружелюбный, что многие разработчики и не собираются учиться программировать. То есть, они требуют готового ответа (расширения) — вынь да положи. Ссылки приводить не буду, достаточно просто поглядеть в блог «Вопросы».
Для тех людей, кому нужна удочка, а не рыба, я расскажу немного про Ajax.
Общие вопросы
Ajax — это метод асинхронного запроса к серверу. Текущая страница html с помощью скрипта обращается к серверу с определенным вопросом, получает ответ и что-то с ним делает. Обычно — вставляет результат в страницу.
На это можно посмотреть на примере голосования за топик. Не стесняйтесь, нажмите на стрелку «вверх» внизу топика — увидите, как она поменяется =)
При клике идет запрос (с параметрами value=1&idTopic=5837&%24family[name]=hash), а в ответ json массив — который обрабатывается и стрелка перерисовывается.
Таким образом, нам нужно 3 элемента: текущая страница, php бэкенд, принимающий запрос и отдающий ответ и скрипт, отправляющий запрос и обрабатывающий ответ.
Как это сделать?
Итак, пишем простейший сниппет для получения запроса:
Сниппет Ajax_test
<?php
// Откликаться будет ТОЛЬКО на ajax запросы
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {return;}
// сниппет будет обрабатывать не один вид запросов, поэтому работать будем по запрашиваемому действию
$action = $_POST['action'];
// Если в массиве POST нет действия - выход
if (empty($action)) {return;}
//А если есть - работаем
$res = '';
switch ($action) {
case 'helloWorld': $res = 'Hello World!'; break;
// А вот сюда потом добавлять новые методы
}
// Если у нас есть, что отдать на запрос - отдаем и прерываем работу парсера MODX
if (!empty($res)) {
die($res);
}
?>
Тут все очевидно: сниппет ловит ajax запросы (а мы все делаем через jquery, который любезно шлет серверу заголовок HTTP_X_REQUESTED_WITH), проверяет, задано ли действие и пытается дать для него ответ.
Пару слов о прерывании парсера. Этот метод я придумал сам, и мне кажется, он гораздо удобнее, нежели использование отдельного php файла.
Лично мне нравится, что мои сниппеты в зависимости от запроса могут работать и через ajax, и просто при обычной загрузке, не завися ни от кого.
Классический же метод состоит в том, чтобы завести отдельный скрипт на сервере, который будет принимать
все ajax запросы, и отвечать на них.
Или создать отдельную страницу, сделать к ней пустой шаблон, запихать туда опять же, один сниппет и прописывать в нем все методы ответов.
В общем, решайте сами, как вам больше нравится, статья моя — пишу как делаю я.
Страница и скрипт
Конечно, мы будем использовать jQuery. Скрипт просто в теле страницы.
<!-- Наш сниппет, при обычной загрузке он ничего не делает -->
[[!Ajax_test]]
<!-- Подключаем jquery с сервера Яндекса -->
<script type="text/javascript" src="http://yandex.st/jquery/1.7.1/jquery.min.js"></script>
<!-- Наш скрипт запроса и обработки -->
<script type="text/javascript">
$(document).ready(function() {
// Вешаем обработчик события "клик" на все ссылки с классом ajax_link
$('a.ajax_link').click(function() {
// Берем действие из атрибута data-action ссылки
var action = $(this).data('action');
// Ajax запрос к текущей страницы (а на ней наш сниппет) методом post
$.post(document.location.href, {action: action}, function(data) {
// Выдаем ответ
alert('Запрос успешно выполнен')
$('#result').html(data);
})
// Не даем ссылке кликнуться - нам же не нужна перезагрузка страницы?
return false;
})
})
</script>
<!-- Ссылка с нужным классом и data - атрибутом, с действием -->
<a href="#" data-action="helloWorld" class="ajax_link">Привет, мир!</a>
<!-- html элемент для вставки ответа от php -->
<div id="result"></div>
Итог
Всего несколько строчек кода и вы можете использовать асинхронные запросы.
Дальше нужно набивать новые методы в сниппет (вызов wayfinder, например), расставлять ссылки по страницам и развешивать обработчики событий на них.
Можно добавить к ссылке новый атрибут data-update="" и писать туда имя элемента для обновления. А при получении ответа вставлять его не в #result, как железно забито сейчас, а в указанный элемент. Тогда вы одними ссылками можете сделать сайт полностью на ajax.
Чуть изменить js скрипт и ссылку попробуйте сами.
Надеюсь, теперь, принцип ясен. Как обычно,
ссылочка проверить.
У меня на страничке добавлена вторая ссылка, с другим data-action, а в сниппете добавлен второй метод ответа:
case 'showMyIp': $res = 'Ваш ip: ' . $_SERVER['REMOTE_ADDR']; break;
Комментарии (32)
RSS свернуть / развернутьSurRealistik
Изначально якоря были придуманы, чтобы перемещаться по большим страницам, без перезагрузок. То есть, при клике на специальную ссылку браузер прокручивает страницу до нужного якоря.
Важная особенность якорей — при их изменении в адресной строке скриптом, страница не перезагружается. А если вы попытаетесь изменить не адрес, а якорь — страница обновиться на новый адрес.
Именно поэтому якоря используют для hash навигации.
Таким образом, якоря можно использовать для хранения промежуточных данных. То есть, нужно при клике взять параметр и сохранить его в якорь, а если страницу обновляем — взять якорь и что то поменять на странице с его учетом.
Типа вот так:
На самом деле, все немного сложнее и индивидуальнее. Для hash навигации нужно хорошенько понимать как что работает. Когда поймете — вопросов не останется =)
bezumkin
В таком случае мы можем делать стандартные макеты, а не те, в которых только контент и загружать страницы асинхронно?
SurRealistik
Ajax придуман для того, чтобы менять куски страницы без перезагрузки. Вы зашли на такую страницу, понатыкали на ней всякого — она изменилась. Но если теперь нажать F5 — она перезагрузится и все изменения пропадут.
Это происходит оттого, что ответы ajax меняют текущую, загруженную страницу. А при обновлении вам сервер выдаст страницу без изменений.
Выходит, что вам нужно получить от сервера страницу и сразу ее изменить? А как изменить? Данные изменений можно хранить на сервере, в сессии — и это будет работать.
Но как тогда дать ссылку на измененную страницу? Вот тут то и нужна hash навигация. Чтобы данные изменения страницы хранить в строке адреса, в якоре.
Таким образом, hash это не альтернатива get-запросам, это место хранения состояния страницы, в нашем случае.
Вот пример
То есть, это просто примочка сбоку для ajax. Сама по себе она ничего не может.
bezumkin
SurRealistik
Ximbo
Спасибо, да идея отличная!
valikras
argnist
Именно jquery такой заголовок и шлет при $.ajax, $.post и $.get
bezumkin
FRo_OG
[[+tv.Catalog__Название]]
[[+tv.Catalog__Название]]
как то так?
FRo_OG
как то так:
?
FRo_OG
FRo_OG
Пример доставания всех tv для ресурса с id 1 на Revolution.
bezumkin
valikras
getObject — можно использовать, если мы укажим к примеру id TV.
valikras
Именно getObject + getMany.
bobsguides.com/revolution-objects.html
bezumkin
valikras
Не мастер-класс ловких методик, а простой и понятный пример оперирования MODX Api.
bezumkin
w3d
Будет работать ВЕЗДЕ!!!
bezumkin
Что не так делаю?
w3d
Исправьте в конце сниппета
на
bezumkin
Evo 1.0.5
w3d
bezumkin
w3d
У Эво сниппет должен быть вставлен вот так:
а не
bezumkin
w3d
При аякс-запросе до своего прерывания в сниппете Ajax парсер обработает вызов сниппета Snippet. Если в этом сниппете ведется, например, подсчет статистики показов баннера на странице, то при каждом аякс-запросе статистика будет увеличиваться, хотя реального показа не будет. Если же расположить Snippet ниже Ajax или в самом сниппете Snippet отключать срабатывание при аякс-запросе, то все будет нормально.
Это просто заметка по поводу возможных грабель, на которые можно наступить.
Ximbo
Ну а уж счетчики страницы так и просто в чанке футера.
bezumkin
и вот про это более подробно «Можно добавить к ссылке новый атрибут data-update=»" и писать туда имя элемента для обновления. А при получении ответа вставлять его не в #result, как железно забито сейчас, а в указанный элемент. Тогда вы одними ссылками можете сделать сайт полностью на ajax."
c4az
bezumkin
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.