Собственно ситуация следующая - есть меню, в котором "переключается" тип новостей, есть новости. Нужно реализовать анимацию меню и соответственно замену новостей без перезагрузки. Следовательно на аяксе. Раньше я бы для решения воспользовался jquery и не ломал бы себе голову. Но захотелось немного разобраться с битриксовым аяксом.
[spoiler]
Что бы было понятно как оно все выглядит покажу кусочек картинки
Справа от заголовка менюшка с "бегунком", по клику эта зеленая блямба двигается.
Тут все просто, кусочек верстки для понимания:
i - наш ползунок, .active - активный пункт меню.
Соответственно для подсветки пунктов смещаем i на 92 пикс для каждой позиции (т.е. для третьего пункта смещение 184 пикс).
Скажу сразу, использую я свои компоненты, поэтому не будем привязываться к чему то конкретному. Что бы компонент меню и компонент новостей заработали на аяксе добавляем в настройки компонента (.parameters.php)
В параметрах соответственно включаем аякс, ЧПУ и выбираем корневую директорию (у меня она /about/press/), ну и в новостях у меня еще параметр для пути к разделу, но тут не важно.
ЧПУ использовали по одной простой причине - ссылки, ведущие куда-либо, кроме текущей странице или которые не будут обрабатываться текущим скриптом будут игнорироваться ajax обработчиком.
Вторая проблема - у нас два разных компонента, при клике на меню в режиме аякс у нас перезагрузится меню, а не новости. Собственно со второй проблемой я и боролся.
Что бы понять какой компонент нужно перегружать на аяксе, битрикс генерирует идентификатор компонента, подменяет ссылки в компоненте и домешивает туда этот идентификатор (ну и идентификатор куда выгружать результат). Потом обработчик со стороны клиента обращается к серверу, передавая в ссылки этот идентификатор, обработчик на стороне сервера (все утрированно) находит наш компонент и отдает результаты его работы, остальное игнорируя. Обработчик на стороне клиента загружает результат на место результата "старого" компонента.
Но нам нужно, что бы перегружался не компонент меню, а компонент новостей. Соответственно будем переопределять js метод, который обращается к серверу (думаю исходник все желающие найдут, помоему файл core_ajax.js):
Самая неприятная часть, идентификатор компонента зависит от его названия, шаблона и ... месте расположения (равно строке). Т.е. если вы подвинете компонент, например, на строчку вниз - вверх, то все сломается...
Собственно в компоненте получить идентификатор можно так:
Ну и в принципе все, имеем два компонента, при этом клик по ссылке в одном приводит к изменению информации в другом компоненте.
PS возможно велосипед, но я старался
[spoiler]
Что бы было понятно как оно все выглядит покажу кусочек картинки
Справа от заголовка менюшка с "бегунком", по клику эта зеленая блямба двигается.
Тут все просто, кусочек верстки для понимания:
<div class="sliderSwitch pressSwitch"> <ul> <li> <a href="#" class="active">Все</a> </li> <li> <a href="#">Новости</a> </li> <li> <a href="#">Пресса</a> </li> </ul> <i style="left:0"></i> <!-- ползунок смещаем на 92px --> </div><!--sliderSwitch--> |
Соответственно для подсветки пунктов смещаем i на 92 пикс для каждой позиции (т.е. для третьего пункта смещение 184 пикс).
$(docu ment).ready(f unction(){ $(".pressSwitch a").live("click", f unction(){ $(".pressSwitch a").removeClass("active"); var indx = parseInt($(this).parent().index()); $(".pressSwitch i").animate({ "left": indx * 92 }, 300); $(this).addClass("active"); //тут бы еще добавить return false; пока наши компоненты меню и вывода новостей не заработали вместе на аяксе }); }); |
"AJAX_MODE" => array(), "SEF_MODE" => array() |
ЧПУ использовали по одной простой причине - ссылки, ведущие куда-либо, кроме текущей странице или которые не будут обрабатываться текущим скриптом будут игнорироваться ajax обработчиком.
Вторая проблема - у нас два разных компонента, при клике на меню в режиме аякс у нас перезагрузится меню, а не новости. Собственно со второй проблемой я и боролся.
Что бы понять какой компонент нужно перегружать на аяксе, битрикс генерирует идентификатор компонента, подменяет ссылки в компоненте и домешивает туда этот идентификатор (ну и идентификатор куда выгружать результат). Потом обработчик со стороны клиента обращается к серверу, передавая в ссылки этот идентификатор, обработчик на стороне сервера (все утрированно) находит наш компонент и отдает результаты его работы, остальное игнорируя. Обработчик на стороне клиента загружает результат на место результата "старого" компонента.
Но нам нужно, что бы перегружался не компонент меню, а компонент новостей. Соответственно будем переопределять js метод, который обращается к серверу (думаю исходник все желающие найдут, помоему файл core_ajax.js):
if (BX .ajax) { BX .ajax.insertToNode = f unction(url, node){ var cid = '20f3a45f3ea80ebe1f458bac9365b56a'; // это идентификатор компонента, который будем перегружать, как его получить расскажу ниже if (cid.length > 0) url = url.r eplace(node.r eplace("comp_", ""), cid); //собственно подмена :) nodeName = 'news_reload'; //свой компонент новостей я обернул в <div id="news_reload">, собственно это идентификатор дива, в который будет выгружен результат работы сервера node = nodeName; if (node = BX (node)) { BX .onCustomEvent('onAjaxInsertToNode', [{ url: url, node: node }]); //здесь я добавил фейда в анимацию, текст у меня плавненько исчезает и появляется после загрузки //думаю пригодится Антону Долганину для этого примера http://dev.1c-bitrix.ru/community/webdev/user/11948/blog/5761/ :) var show = null; $("#" + nodeName).fadeOut(300, f unction(){ $(this).empty().show(); show = BX .showWait(node); return BX .ajax.get(url, f unction(data){ BX .closeWait(node, show); $("#" + nodeName).hide(); node.innerHTML = data; $("#" + nodeName).fadeIn(300); }); }); } } } |
Собственно в компоненте получить идентификатор можно так:
$componentID = CAjax::GetComponentID($this->__name, $this->__templateName, false); |
PS возможно велосипед, но я старался