Вступление
Посещаю Хабр уже давно, но на статью решился только сейчас. Да и то, не статья это вовсе, а так — скорее, заметка о том, как легко и без напряга, без правки ядра и заморочек с самим аяксом взять и заменить стандартное убогое окошко прелоадера битрикса на свой произвольный 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
Всем спасибо за внимание!
Sombressoul
Вот именно поэтому я с Битриксом больше не работаю. Потому что каждая такая «смена прелоадера» требует реверс-инженеринга его собственной JS библиотеки на пол-метра, суток бомбардировки Гугла, переписки с ТП, а потом переосмысления сущности бытия и написания ~80 строк кода.
Опыт работы под Битрикс — 3 года (включая собственные компоненты). За это время разучился «программировать», зато научился «сношаться с Битриксом». И статья на тему «как сменить прелоадер» с листингом кода на три экрана — хороший тому пример.
В общем:
— Если вместо решения задачи при помощи системы приходится бороться с самой системой — это плохая система.
Itachi261092
Самым правильным подходом для такой задачи, является изучение родного аякса и jquery битрикса. А это мало кто делает. Включая меня и Вас. Любой опытный битриксоид подтвердит, что для успешной работы с этой CMS, необходимо очень хорошо изучить всю документацию. Без этого, увы, никак.
Sombressoul
Справедливости ради, стоит отметить, что с документацией у Битрикса далеко не всё гладко. В частности, если уж и говорить про его родную библиотеку BX.js, то на тот момент когда мои нервы сдали и я отвернулся от этой системы, вся документация по этой жирнющей библиотеке сводилась к вордовскому файлику из двух страниц с содержанием в духе «смотрите, у нас есть такая библиотека». Но это было пару лет назад.
Да, кстати, на тот момент, если мне не изменяет память, они ещё не придумали включить в дистрибутив кастомизированный jquery. Но если это действительно так, то у меня возникают вопросы об обоснованности решения о кастомизации библиотеки, которая успешно используется на многих миллионах сайтов в неизменном виде.
В силу своего знакомства с принципами работы jquery и её исходниками, я просто не могу представить, честно говоря, для каких целей её необходимо было модифицировать, потому как задачи, для которых она создана, она выполняет на все 100, а все прочие задачи можно решить на её основе путём создания плагинов.
Если просветите по этому вопросу — буду благодарен. Просто интересно.
Itachi261092
Я никогда не видел документации успевающей за разработкой. Вот пример того как выглядит раздел документации по аяксу битрикса сейчас.
Кастомизация jquery, насколько я понимаю, у них не сильная — они просто стилизовали всплывающие окна под стиль админки и т.п. и ещё пытались настроить единое подключение jquery с автоматическим выбором версии. Но Сейчас это не всегда работает. Это было сделано чтобы минимизировать ошибки на сайтах, которые используют много сторонних фреймворков на jquery, которые каждый требует определённую версию.