Загрузка страницы..
Как легко и быстро поставить свой прелоадер на стандартный AJAX Битрикса?
Замена стандартного прелоада Битрикс
2015-11-19T11:11 19 нояб. 2015 11:11
Просмотров: 2233

Вступление

Посещаю Хабр уже давно, но на статью решился только сейчас. Да и то, не статья это вовсе, а так — скорее, заметка о том, как легко и без напряга, без правки ядра и заморочек с самим аяксом взять и заменить стандартное убогое окошко прелоадера битрикса на свой произвольный HTML/CSS код. Приступим?

Описание проблемы

Разработчики на 1С-Битрикс должны знать об этой проблеме, а для всех непосвящённых — поясню. Эта CMS использует в стандартных шаблонах и компонентах свой кастомный jquery и ajax. Документация имеется, но много ли кому охото её изучать, чтобы сделать какие то элементарные вещи?.. В принципе, если ничего в стандартных шаблонах не трогать, «родной» аякс битрикса работает не плохо. Но если попытаться что то серьёзно подправить, или вовсе — натягивать свою вёрстку в купе с родным аяксом — тут начинаются танцы с бубном, и такая элементарная вещь, как замена дефолтного убогого прелоадера, превращается в нудное гугление и изучение кода в ядре CMS.

Позиция ТП Битрикса на этот счёт вообще удивляет:

Сейчас, к сожалению, нет стандартного способа изменить стандартный прелоадер

Все самые наивные и доверчивые скажут «нельзя? ну ок...» и пойдут писать свои аякс-запросы. А мы возьмём и сделаем!

Реализация

Суть проста — у стандартного аякса есть две функции BX.showWait и BX.closeWait которые отвечают за действия на странице в момент ожидания ответа от аякса. Используем их чтобы подгрузить вместо дефолтного прелоадера, свой.

Для начала найдём сам прелоадер. Мне например, понравился на чистом HTML/CSS в стиле Windows 8. Затем открываем footer.php нашего шаблона и перед тегом вписываем наш код:

<div id="win8_wrapper">
	<div class="windows8">
		<div class="wBall" id="wBall_1">
			<div class="wInnerBall"></div>
		</div>
		<div class="wBall" id="wBall_2">
			<div class="wInnerBall"></div>
		</div>
		<div class="wBall" id="wBall_3">
			<div class="wInnerBall"></div>
		</div>
		<div class="wBall" id="wBall_4">
			<div class="wInnerBall"></div>
		</div>
		<div class="wBall" id="wBall_5">
			<div class="wInnerBall"></div>
		</div>
	</div>
</div>

Длинную CSS-простыню вставлять не буду (в конце будут все исходники). Далее вставляем скрипт с вызовом функций, которые подгрузят наш прелоадер вместо стандартного:

var lastWait = [];
	/* non-xhr loadings */
	BX.showWait = function (node, msg)
	{
		node = BX(node) || document.body || document.documentElement;
		msg = msg || BX.message('JS_CORE_LOADING');

		var container_id = node.id || Math.random();

		var obMsg = node.bxmsg = document.body.appendChild(BX.create('DIV', {
			props: {
				id: 'wait_' + container_id,
				className: 'bx-core-waitwindow'
			},
			text: msg
		}));

		setTimeout(BX.delegate(_adjustWait, node), 10);

		$('#win8_wrapper').show();
		lastWait[lastWait.length] = obMsg;
		return obMsg;
	};

	BX.closeWait = function (node, obMsg)
	{
		$('#win8_wrapper').hide();
		if (node && !obMsg)
			obMsg = node.bxmsg;
		if (node && !obMsg && BX.hasClass(node, 'bx-core-waitwindow'))
			obMsg = node;
		if (node && !obMsg)
			obMsg = BX('wait_' + node.id);
		if (!obMsg)
			obMsg = lastWait.pop();

		if (obMsg && obMsg.parentNode)
		{
			for (var i = 0, len = lastWait.length; i < len; i++)
			{
				if (obMsg == lastWait[i])
				{
					lastWait = BX.util.deleteFromArray(lastWait, i);
					break;
				}
			}

			obMsg.parentNode.removeChild(obMsg);
			if (node)
				node.bxmsg = null;
			BX.cleanNode(obMsg, true);
		}
	};

	function _adjustWait()
	{
		if (!this.bxmsg)
			return;

		var arContainerPos = BX.pos(this),
			div_top = arContainerPos.top;

		if (div_top < BX.GetDocElement().scrollTop)
			div_top = BX.GetDocElement().scrollTop + 5;

		this.bxmsg.style.top = (div_top + 5) + 'px';

		if (this == BX.GetDocElement())
		{
			this.bxmsg.style.right = '5px';
		}
		else
		{
			this.bxmsg.style.left = (arContainerPos.right - this.bxmsg.offsetWidth - 5) + 'px';
		}
	}

Ну и не забываем обязательно добавить CSS стили вашего прелоадера стандартным способом — скопировав в template_styles.css либо подключив в header.php отдельным файлом.

Пробуем что нибудь пощёлкать на сайте. Вуаля — прелоадер заменён. Для более «правильного» метода я бы советовал вынести подключение в футере в отдельную включаемую область.

Исходники на GitHub


Исходная статья



Комментарии: 4

комментарий Itachi261092
Itachi261092
2015-11-21T03:5921 нояб. 2015 03:59
показать всё Sombressoul, Я никогда не видел документации успевающей за разработкой. Вот пример того как выглядит раздел документации по аяксу битрикса сейчас. Кастомизация jquery, насколько я понимаю, у них не сильная — они просто стилизовали всплывающие окна под стиль админки и т.п. и ещё пытались настроить единое подключение jquery с автоматическим выбором версии. Но Сейчас это не всегда работает. Это было сделано чтобы минимизировать ошибки на сайтах, которые используют много сторонних фреймворков на jquery, которые каждый требует определённую версию.
комментарий Sombressoul
Sombressoul
2015-11-21T03:5121 нояб. 2015 03:51
показать всё Itachi261092, Справедливости ради, стоит отметить, что с документацией у Битрикса далеко не всё гладко. В частности, если уж и говорить про его родную библиотеку BX.js, то на тот момент когда мои нервы сдали и я отвернулся от этой системы, вся документация по этой жирнющей библиотеке сводилась к вордовскому файлику из двух страниц с содержанием в духе «смотрите, у нас есть такая библиотека». Но это было пару лет назад.

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

В силу своего знакомства с принципами работы jquery и её исходниками, я просто не могу представить, честно говоря, для каких целей её необходимо было модифицировать, потому как задачи, для которых она создана, она выполняет на все 100, а все прочие задачи можно решить на её основе путём создания плагинов.

Если просветите по этому вопросу — буду благодарен. Просто интересно.
комментарий Itachi261092
Itachi261092
2015-11-21T03:5021 нояб. 2015 03:50
Sombressoul, Самым правильным подходом для такой задачи, является изучение родного аякса и jquery битрикса. А это мало кто делает. Включая меня и Вас. Любой опытный битриксоид подтвердит, что для успешной работы с этой CMS, необходимо очень хорошо изучить всю документацию. Без этого, увы, никак.
комментарий Sombressoul
Sombressoul
2015-11-21T03:2521 нояб. 2015 03:25
показать всё Вот именно поэтому я с Битриксом больше не работаю. Потому что каждая такая «смена прелоадера» требует реверс-инженеринга его собственной JS библиотеки на пол-метра, суток бомбардировки Гугла, переписки с ТП, а потом переосмысления сущности бытия и написания ~80 строк кода.

Опыт работы под Битрикс — 3 года (включая собственные компоненты). За это время разучился «программировать», зато научился «сношаться с Битриксом». И статья на тему «как сменить прелоадер» с листингом кода на три экрана — хороший тому пример.

В общем: — Если вместо решения задачи при помощи системы приходится бороться с самой системой — это плохая система.

Добавить комментарий

Яндекс.Метрика Яндекс.Метрик