Динамическое меню каталога товаров в Demodizzy
В данной статье речь пойдет о том как немного украсить ваш сайт и сделать его более интерактивным. И так, ниже будет описан простой способ сделать анимированное меню каталога с помощью методов jquery ui.
Задача: Сделать двухуровневое меню, второй уровень которого по умолчанию скрыт. При наведении мыши на какой либо раздел меню, снизу от него должны плавно выезжать подразделы. При наведении курсора на другой пункт меню, старые подразделы должны исчезать, и появятся новые, в соответствии с выбранным пунктом меню.
И так, для начала нам потребуется в шаблоне нашего сайта подключить все необходимые библиотеки jquery. Так как в UMI уже, по умолчанию, подключена основная библиотека jquery, нам потребуется лишь подключить скрипты эффектов и файл с нашим будущим кастомным скриптом. Так как в нашем примере мы рассматриваем верстку на основе XSLT то соответственно скрипты должны быть вставлены в файл, где прописана верстка тегов <head> (по умолчанию - ~\templates\demodizzy\xslt\layouts\default.xsl)
Нужные нам скрипты подключаются следующим образом:
<script charset="utf-8" src="/templates/demodizzy/js/jquery.effects.core.js" type="text/javascript"></script>
Соответственно файл jquery.effects.core.js нужно скачать с официального сайта Jquery.
И теперь подключим непосредственно наш будущий скрипт. Для данного примера назовем его My.js и положим в папку ~/templates/demodizzy/js/
<script charset="utf-8" src="/templates/demodizzy/js/My.js" type="text/javascript"></script>
Следующим нашим действием будет добавление дополнительных тегов в верстку сайта, необходимых для работы скрипта.
Файл отвечающий за левое меню находится: ~\templates\demodizzy\xslt\modules\catalog\left-column-category-list.xsl
Изначально, интересующий нас блок выглядит следующим образом:
<xsl:template match="udata[@method = 'getCategoryList']//item" mode="left-column">
<li umi:element-id="{@id}" umi:region="row">
<span>
<a href="{@link}" umi:field-name="name" umi:delete="delete" umi:empty="&empty-section-name;">
<xsl:value-of select="." />
</a>
</span>
<xsl:apply-templates select="document(concat('udata://catalog/getCategoryList/void/', @id))" />
</li>
</xsl:template>
Добавим дополнительные теги, для javascript:
<xsl:template match="udata[@method = 'getCategoryList']//item" mode="left-column">
<div class="cat1">
<li umi:element-id="{@id}" umi:region="row" >
<span onMouseOver="open_menu(this)" >
<a href="{@link}" umi:field-name="name" umi:delete="delete" umi:empty="&empty-section-name;">
<xsl:value-of select="." />
</a>
</span>
<div class="cat2" style="display: none; height:1">
<xsl:apply-templates select="document(concat('udata://catalog/getCategoryList/void/', @id, '//1/'))" />
</div>
</li>
</div>
</xsl:template>
Некоторое пояснение к тому что именно мы добавили. Вызов отвечающий за вывод подменю мы окружили тегом
<div class="cat2" style="display: none; height:1">
Параметр style="~" отвечает за настройки стиля
display: none настройка стиля, согласно которой объект не отображается на странице
height:1 настройка стиля, согласно которой высота объекта = 1
Тег отвечающий за вызов названий разделов имеет следующий вид
<span onMouseOver="open_menu(this)" >
параметр onMouseOver="open_menu(this)" обозначает что при наведении мыши на данный объект будет вызываться javascript функция open_menu(), в которую будет передаваться значение объекта вызвавшего ее.
Теперь нужно написать сам скрипт, а точнее функцию, которая вызывается при наведении мыши на объект (название) Для этого откроем, пока еще пустой файл My.js, который мы подключили выше и напишем следующий скрипт:
var elems_old = "";
var block = 0;
var menu_speed = 500; //переменная отвечающая за скорость выпадающего меню
var menu_height = 100; //переменная отвечающая за высоту блока (данный скрипт не будет вычислять ее автоматически)
// функция которая вызывается при наведении мыши
function open_menu(elems){
//условие - если тригер блокировки стоит в 1, то функция не выполнится
// функция выполнися если переданное значенеие объекта отличается от старого (сработает только если мы выбрали новый пункт меню)
if(block == 0 && elems_old != elems){
//сразу блокируется, чтобы не выполнять алгоритм повторно
block = 1;
action_menu(elems);}
}
function action_menu(elems){
if ( elems_old != 0 ){
//выбираем потомка нашего элемента (в данном случае это будет подменю, соответствующее пункту меню.)
elems_a = elems_old.parentNode.childNodes[2];
//анимированно сворачиваем его
$( elems_a ).animate({height: 1, queue:true}, menu_speed, callback(elems_a) );
}
elems_c = elems.parentNode.childNodes[2];
//разворачиваем с анимацией выбранный пункт меню
$( elems_c ).animate({height: menu_height, queue:true}, menu_speed);
// Делаем элемент видимым
elems_c.style.display=""
elems_old = elems;
// снимаем блокировку
setTimeout(function() { block = 0; }, 100)
}
function callback(elems_a) {
//делаем исчезающий элемент невидимым
setTimeout(function() { elems_a.style.display="none"; }, menu_speed)
}
Все. Теперь на вашем сайте должно получится красивое анимированное меню каталога. Для того чтобы сделать его более удобным, также, следует увеличить размер пунктов меню в таблице CSS стилей.