Собственно ситуация следующая - есть меню, в котором "переключается" тип новостей, есть новости. Нужно реализовать анимацию меню и соответственно замену новостей без перезагрузки. Следовательно на аяксе. Раньше я бы для решения воспользовался 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 возможно велосипед, но я старался
