AjaxSnippet - отложенное выполнение сниппетов (Evo).

Если какой-либо сниппет отрабатывает дюже долго, то его стоит, конечно, сперва попробовать оптимизировать. Но если лень или он и так максимально ускорен, то на помощь придет решение ниже. Создаем сниппет AjaxSnippet, вставляем в него код. Далее вместо вызова вашего сниппета, вызываем вновь созданный с дувумя обязательными параметрами: &as_id — уникальный id вызова и &snippet — название исполняего сниппета. Остальные параметры наследуются от основного.

Т.е. если у вас вызов:
[ [DocLister?
&tpl=`@CODE: [+pagetitle+]`
...
] ]

то нужно поменять на
[ [AjaxSnippet?
&as_id=`test`
&snippet=`DocLister`
&tpl=`@CODE: [+pagetitle+]`
&preloader=`@CODE: загрузка. Если не писать собакокод - будет искать чанк с названием`
...
] ]

Ну и сам код:
<?php
if ((!$snippet) || (!$as_id)) return;
if ($_GET['ajax']==$as_id)
{
	echo $modx->runSnippet($snippet,$params);
	exit();
}
else
{	
	$url = ((!empty($_SERVER['HTTPS'])) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
	if ($preloader)
	{
		if (substr($preloader,0,6)=='@CODE:') $preloader = str_replace('@CODE:','',$preloader);
		else $preloader = $modx->getChunk($preloader);
	}
	if (count($_GET)) $s = '&';
	else $s = '?';
	return '
	< script >
		document.addEventListener("DOMContentLoaded", function(){
			const request_'.$as_id.' = new XMLHttpRequest(); 			
			request_'.$as_id.'.open("GET", "'.$url.$s.'ajax='.$as_id.'");
			request_'.$as_id.'.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			request_'.$as_id.'.addEventListener("readystatechange", () => {
				{
					if (request_'.$as_id.'.readyState === 4 && request_'.$as_id.'.status === 200) {						
						document.getElementById("'.$as_id.'").innerHTML = request_'.$as_id.'.responseText;						
					}
				}});
			request_'.$as_id.'.send();
		});
	</ script >
	<div id="'.$as_id.'">'.$preloader.'</div>';
}

В тэге script нужно убрать пробелы.
Ну и есть пара отличий от версии Наумкина. Первое — при вызове учитываются GET-параметры. Второе — используется нативный Javacript. Да, код универсальный, пойдет на обе ветки.

3 комментария

avatar
Оно в те времена выглядело бредом, а сейчас и подавно.
avatar
Не понял, зачем.
На худой конец есть $.ajax и у него события beforeSend и complete. Вызывать через обычный аякс тогда и дело с концом. Или что-то тут хитрое в коде и я как всегда протупил?
  • 1px
  • 0
avatar
Хитрого нет ничего абсолютно. Код прост до безобразия. Но:
а) работает без jQuery
б) не нужно ничего нигде дополнительного прописывать. Просто изменил название сниппета, добавил пару параметров и он работает.
С тем же подтекстом можно сказать про любое готовое универсальное упрощение.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.