То что выше получится в конце урока для отладки стилей вы можете использовать плагин Firebug для FireFox.
Но давайте по порядку. Я решил выводить список категории сайта в горизонтальное меню Аккордеон использовавший фреймворк MooTools, возможные осложнения при использование MooTools это не работаспособность скриптов использующих
JQuery для решения этои проблемы используйте функцию noConflict().
Html разметка будет выглядеть следующим образом:
<div id="accordion_menu">
<div style="width: 200px;">
<h3 class="toggler toggler_parent "><span class="menu_left"><span><a href="/" class="mainlevel">HOME</a></span></span></h3>
<div style="display: block; border: medium none; overflow: hidden; padding: 0px; margin: 0px; visibility: hidden; opacity: 0; height: 0px;" class="accordion_menu_element"></div><h3 id="current_2 " class="toggler toggler_parent "> <span class="menu_left"><span>
<a class="mainlevel" href="/kategoriya-1">Категория 1</a></span></span></h3>
<div style="display: block; border: medium none; overflow: hidden; padding: 0px; margin: 0px; visibility: hidden; opacity: 0; height: 0px;" class="accordion_menu_element"></div><h3 id="current_3 " class="toggler toggler_parent "> <span class="menu_left"><span>
<a class="mainlevel" href="/kategoriya-2">Категория 2</a></span></span></h3>
<div style="display: block; border: medium none; overflow: hidden; padding: 0px; margin: 0px; visibility: hidden; opacity: 0; height: 0px;" class="accordion_menu_element"></div><h3 class="toggler toggler_open toggler_parent "><span class="menu_left"><span><a href="/kategoriya3" class="mainlevel"><span>Категория3</span></a></span></span> </h3>
<div style="display: block; border: medium none; overflow: hidden; padding: 0px; margin: 0px; visibility: visible; opacity: 1; height: 16px;" class="accordion_menu_element"><ul class="menu_p"> <li><a href="/kategoriya31" class="mainlevel">Категория31</a></li> </ul></div><script type="text/javascript">
var am_parent_link_enabled = "1";
var accordion_menu_display = "block";
</script>
<script type="text/javascript" src="/templates/Default/js/menu_a.js"></script>
</div>
</div>
Рассмотрим её подробнее.
Родительский элемент
<div id="accordion_menu">
В нём содержатся наши категории, блочный элемент div имеет свой идентификатор accordion_menu который используется в таблице стилей для
определения своист вложенных элементов.Следующии элемент div определяет размер блока по горизонтали (я установил 200px)
<div style="width: 200px;">
Сдесь мы начнем определять внешний вид заголовков с помощью каскаднои таблицы стилей (.css) рассмотрим своиства первого элемента H3:
<html
<h3 class="toggler toggler_parent "><span class="menu_left"><span><a href="/" class="mainlevel">HOME</a></span></span></h3>
html>
<css
#accordion_menu h3 { margin:0; padding:0; line-height:33px; }
#accordion_menu h3.toggler_parent { cursor: pointer; font-size: 12px; background: url(../js/images/acc_0.png) 100% -23px no-repeat; height:33px; padding-right:24px!important; }
#accordion_menu h3.toggler_open { background: url(../js/images/acc_0.png) 100% 5px no-repeat; padding-right:24px!important; height:32px; }
#accordion_menu h3.toggler_open a { display:block; width: auto; float:left; height:32px; background:transparent; color:black; text-decoration:none; font-size:103%; font-weight:800; }
#accordion_menu h3.toggler div { margin:0px; padding:0px; }
#accordion_menu h3.toggler a.mainlevel { display:block; width: auto; float:left; height:32px; background:transparent; color:black; text-decoration:none; font-size:103%; font-weight:800; white-space:nowrap }
css>
Как видите в заголовке присутствуют несколько элементов span и ссылка на домашнюю страницу, в нашем случае мы используем span для оформления блоков по умолчанию блок считается закрытым и ему присвоен класс toggler_parent при нажатие на элемент h3 скрипт присвоит ему класс toggler_open как видно из своиств стилей произойдет изменение положения фонового изображения у данного элемента.
#accordion_menu h3.toggler_parent { cursor: pointer; font-size: 12px; background: url(../js/images/acc_0.png) 100% -23px no-repeat;)
#accordion_menu h3.toggler_open { background: url(../js/images/acc_0.png) 100% 5px no-repeat; )
В свойстве h3.toggler_parent фон сдвинут по вертикали на -23 пикселя от 0 (картинка смещается вверх по оси y) , в h3.toggler_open на 5 пикселейот 0 (к начальному значению 0 прибавляется 5px и картинка смещается вниз) так как строчному элементу h3 присвоено своиство line-height:33px; то будет показана толька та часть картинки котораяя попадает в поле видимости 32пикселя, такой метод называют спрайтами об этом есть много статей и мы не будем подробно останавливаться на его изучении.
Также элемент h3 является кнопкои Открыть-Закрыть для блока содержащего дочерний элементы в нашем случае под категории
<h3 class="toggler toggler_open toggler_parent "><span class="menu_left"><span><a href="/kategoriya3" class="mainlevel"><span>Категория3</span></a></span></span> </h3>
<div style="display: block; border: medium none; overflow: hidden; padding: 0px; margin: 0px; visibility: visible; opacity: 1; height: 16px;" class="accordion_menu_element"><ul class="menu_p"> <li><a href="/kategoriya31" class="mainlevel">Категория31</a></li> </ul></div>
Как видите класс у открытого элемента изменен на toggler toggler_open toggler_parent, хотя и используется два определения класса элемента, приоритет будет у toggler_open так как оно объявлено позже toggler_parent и переопределяет его.(можете поэксперементировать и поменять местами данные свойства и убедитесь в том что правило последний главный работает ) ), Основное думаю понятно с html разметкой мы закончили
начнем формирование цикла вывода.
Создадим функцию с произвольным именем у меня это menu и определим переменные, значения которых нам понадобятся в цикле формирования html кода.
function menu( $menu_arr )
{
global $category_id, $cat_info,$config;
}
Далее определим две вспомогательные функции которые будут использоваться в цикле
function search_children( $arr, $style = "parent", $menu_name = "/" )//Поиск детей
{
global $category_id,$config;
$base .= <<< HTML
<li class="parent"><ul class="menu_p_p">
HTML;
foreach ( $arr as $val ) {
if ( $category_id == $val['id'] ) $tyy = "id="parent_activ"";
else $tyy = "";
$base .= <<< HTML
<li class="item_$style"><a class="mainlevel" href="{$config['http_home_url'] }$menu_name/{$val['alt_name']}" $tyy ><span>{$val['name']}</span></a> </li>
HTML;
if ( $val['children'] ) $base .= search_children( $val['children'], "child", $val['alt_name'] );
}
$base .= "</ul></li>";
return $base;
}
function SetTrrigger( $arr, $r = 0 )//Установкка указателя на категорию где находимся
{
global $category_id, $cat_info;
$trigger = 0;
if ( $cat_info[$r]['parentid'] ) {
$r = $cat_info[$r]['parentid'];
$trigger = SetTrrigger( $arr, $r );
}
else $trigger = $cat_info[$r]['id'];
return $trigger;
}
Как видно из названии функции первая будет искать дочерний элементы в массиве переданном в функцию menu, вторая установит указатель на
пункт где находится пользователь в виде стрелочки (анимации).
Устанавливаем указатель trigger, начинаем вывод структуры html нашего меню:
$trigger = SetTrrigger( $menu_arr, $category_id );
$output .= <<< HTML
<div id="accordion_menu">
<div style="width:200px; ">
HTML;
$output .= <<< HTML
<h3 class="toggler toggler_parent" ><span class="menu_left"><span><a class="mainlevel" href="/">HOME</a></span></span></h3>
<div class="accordion_menu_element" style="display: none; border:none; overflow: hidden; padding: 0px; margin: 0px"></div>
HTML;
*Небольшое примечание чтобы Аккордеон работал мы будем выводить дочерний элемент для каждого пункта даже если он не имеет Детей.
Запускаем цикл foreach формирующий список категории:
foreach ( $menu_arr as $menu_rec ) {
if ( ! $menu_rec['children'] ) {//Если нет детей выводим 1 блок
$output .= <<< HTML
<h3 class="toggler toggler_parent" id="current_{$menu_rec['id']} "> <span class="menu_left"><span>
<a href="{$config['http_home_url'] }{$menu_rec['alt_name']}" class="mainlevel">{$menu_rec['name']}</a></span></span></h3>
<div class="accordion_menu_element" style="display: none; border:none; overflow: hidden; padding: 0px; margin: 0px"></div>
HTML;
} elseif ( $menu_rec['children'] ) {// Если дети есть запускаем второй цикл и проверяем нет ли детей у данного ребёнка
if ( $menu_rec['id'] === $trigger ) {
$output .= <<< HTML
<h3 class="toggler toggler_parent"><span class="menu_left"><span>
<a href="{$config['http_home_url'] }{$menu_rec['alt_name']}" class="mainlevel"> <span class="tregger"> {$menu_rec['name']}</span></a></span></span> </h3>
<div class="accordion_menu_element" style="display: none; border:none; overflow: hidden; padding: 0px; margin: 0px">
<ul class="menu_p">
HTML;
foreach ( $menu_rec['children'] as $val ) {
if ( $category_id == $val['id'] ) $tyy = "id="parent_activ"";
else $tyy = "";
$output .= <<< HTML
<li ><a href="{$config['http_home_url'] }{$val['alt_name']}" class="mainlevel" $tyy > {$val['name']} </a></li>
HTML;
if ( $val['children'] ) {
$output .= search_children( $val['children'], "", $menu_rec['alt_name'] );
}
}
}
else {
$output .= <<< HTML
<h3 class="toggler toggler_parent" ><span class="menu_left"><span><a class="mainlevel" href="{$config['http_home_url'] }{$menu_rec['alt_name']}"><span>{$menu_rec['name']}</span></a></span></span> </h3>
<div class="accordion_menu_element" style="display: none; border:none; overflow: hidden; padding: 0px; margin: 0px"><ul class="menu_p">
HTML;
foreach ( $menu_rec['children'] as $val ) {
$output .= <<< HTML
<li><a class="mainlevel" href="{$config['http_home_url'] }{$val['alt_name']}">{$val['name']}</a></li>
HTML;
if ( $val['children'] ) {
$output .= search_children( $val['children'], "", $menu_rec['alt_name'] );
}
}
}
$output .= "</ul></div>";
}
}
Завешаем структуру html блока и возвращаем из функции код:
$output .= <<< HTML
<script type="text/javascript">
var am_parent_link_enabled = "1";
var accordion_menu_display = "block";
</script>
<script src="{THEME}/js/menu_a.js" type="text/javascript"></script>
</div>
</div>
HTML;
return $output;
Исходная функция меню теперь содержит в себе две вспомогательные функции и цикл вывода html кода:
function menu( $menu_arr )
{
global $category_id, $cat_info,$config;
function search_children( $arr, $style = "parent", $menu_name = "/" )//Поиск детей
{
global $category_id,$config;
$base .= <<< HTML
<li class="parent"><ul class="menu_p_p">
HTML;
foreach ( $arr as $val ) {
if ( $category_id == $val['id'] ) $tyy = "id="parent_activ"";
else $tyy = "";
$base .= <<< HTML
<li class="item_$style"><a class="mainlevel" href="{$config['http_home_url'] }$menu_name/{$val['alt_name']}" $tyy ><span>{$val['name']}</span></a> </li>
HTML;
if ( $val['children'] ) $base .= search_children( $val['children'], "child", $val['alt_name'] );
}
$base .= "</ul></li>";
return $base;
}
function SetTrrigger( $arr, $r = 0 )//Установкка указателя на категорию где находимся
{
global $category_id, $cat_info;
$trigger = 0;
if ( $cat_info[$r]['parentid'] ) {
$r = $cat_info[$r]['parentid'];
$trigger = SetTrrigger( $arr, $r );
}
else $trigger = $cat_info[$r]['id'];
return $trigger;
}
$trigger = SetTrrigger( $menu_arr, $category_id );
$output .= <<< HTML
<div id="accordion_menu">
<div style="width:200px; ">
HTML;
$output .= <<< HTML
<h3 class="toggler toggler_parent" ><span class="menu_left"><span><a class="mainlevel" href="/">HOME</a></span></span></h3>
<div class="accordion_menu_element" style="display: none; border:none; overflow: hidden; padding: 0px; margin: 0px"></div>
HTML;
foreach ( $menu_arr as $menu_rec ) {
if ( ! $menu_rec['children'] ) {//Если нет детей выводим 1 блок
$output .= <<< HTML
<h3 class="toggler toggler_parent" id="current_{$menu_rec['id']} "> <span class="menu_left"><span>
<a href="{$config['http_home_url'] }{$menu_rec['alt_name']}" class="mainlevel">{$menu_rec['name']}</a></span></span></h3>
<div class="accordion_menu_element" style="display: none; border:none; overflow: hidden; padding: 0px; margin: 0px"></div>
HTML;
} elseif ( $menu_rec['children'] ) {// Если дети есть запускаем второй цикл и проверяем нет ли детей у данного ребёнка
if ( $menu_rec['id'] === $trigger ) {
$output .= <<< HTML
<h3 class="toggler toggler_parent"><span class="menu_left"><span>
<a href="{$config['http_home_url'] }{$menu_rec['alt_name']}" class="mainlevel"> <span class="tregger"> {$menu_rec['name']}</span></a></span></span> </h3>
<div class="accordion_menu_element" style="display: none; border:none; overflow: hidden; padding: 0px; margin: 0px">
<ul class="menu_p">
HTML;
foreach ( $menu_rec['children'] as $val ) {
if ( $category_id == $val['id'] ) $tyy = "id="parent_activ"";
else $tyy = "";
$output .= <<< HTML
<li ><a href="{$config['http_home_url'] }{$val['alt_name']}" class="mainlevel" $tyy > {$val['name']} </a></li>
HTML;
if ( $val['children'] ) {
$output .= search_children( $val['children'], "", $menu_rec['alt_name'] );
}
}
}
else {
$output .= <<< HTML
<h3 class="toggler toggler_parent" ><span class="menu_left"><span><a class="mainlevel" href="{$config['http_home_url'] }{$menu_rec['alt_name']}"><span>{$menu_rec['name']}</span></a></span></span> </h3>
<div class="accordion_menu_element" style="display: none; border:none; overflow: hidden; padding: 0px; margin: 0px"><ul class="menu_p">
HTML;
foreach ( $menu_rec['children'] as $val ) {
$output .= <<< HTML
<li><a class="mainlevel" href="{$config['http_home_url'] }{$val['alt_name']}">{$val['name']}</a></li>
HTML;
if ( $val['children'] ) {
$output .= search_children( $val['children'], "", $menu_rec['alt_name'] );
}
}
}
$output .= "</ul></div>";
}
}
$output .= <<< HTML
<script type="text/javascript">
var am_parent_link_enabled = "1";
var accordion_menu_display = "block";
</script>
<script src="{THEME}/js/menu_a.js" type="text/javascript"></script>
</div>
</div>
HTML;
return $output;
}
;
Вызываем функцию:
$cat_info2 = SortCategoriesArray( $cat_info );
echo menu( $cat_info2 );
В файл стилей engine.css (или другой вам виднее) добавляем стили:
#accordion_menu a { font-size:100%!important; }
#accordion_menu h3 { margin:0; padding:0; line-height:33px; }
#accordion_menu h3.toggler_parent { cursor: pointer; font-size: 12px; background: url(../js/images/acc_0.png) 100% -23px no-repeat; height:33px; padding-right:24px!important; }
#accordion_menu h3.toggler_open { background: url(../js/images/acc_0.png) 100% 5px no-repeat; padding-right:24px!important; height:32px; }
#accordion_menu h3.toggler_open a { display:block; width: auto; float:left; height:32px; background:transparent; color:black; text-decoration:none; font-size:103%; font-weight:800; }
#accordion_menu h3.toggler div { margin:0px; padding:0px; }
#accordion_menu h3.toggler a.mainlevel { display:block; width: auto; float:left; height:32px; background:transparent; color:black; text-decoration:none; font-size:103%; font-weight:800; white-space:nowrap }
div.accordion_menu_element li { list-style-image:none; list-style-position:outside; list-style-type:none; padding-left:15px; }
div.accordion_menu_element li a { font-size:11px; }
div.accordion_menu_element { width:auto; }
ul.menu_p { padding-bottom:0px; padding-left:0px; margin-left:0px; margin:0 5px 0 5px; background:#d5f0fb; border:1px solid #ececef; border-top:none; }
ul.menu_p_p { padding-bottom:0px; padding-left:0px; margin-left:0px; margin:0 5px 0 5px; }
ul.menu_p a:hover { text-decoration:underline; }
ul.menu_p li { padding-left:5px; }
*+html ul.menu_p li.parent { padding-left:5px; padding-top:0; margin:0; }
ul.menu_p li a { font:Tahoma, Geneva, sans-serif; color:#363636; text-decoration:none; padding:0 0 3px 17px; }
ul.menu_p span { height:12px; }
span.menu_left { background:url(../js/images/acc_1.png) 0 4px no-repeat; width:100%; height:32px; float:left; display:block; padding:0 0 0 6px; }
span.menu_left span { background: url(../js/images/acc_2.png) 0 4px repeat-x; width:96%; height:32px; float:left; display:block; }
a.mainlevel span.tregger { background: url(../js/images/arrow.gif) left no-repeat; padding:0 0 0 25px; height:25px; display:block; }
a#parent_activ { font:Tahoma, Geneva, sans-serif; font-size:100%; color:red; text-decoration:none; line-height:18px; padding:0 0 0 17px; background:url(../js/images/arrow_2.gif) left no-repeat; }
Урок закончен
В исходниках найдети скрипты .js ,.php ..psd оформленяи блоков ( для корекции цвета используйте коректирующий слои который присутствует) )
ps. В версии DLE 9.0 данный пример будет вызывать конфликт скриптов из за использования MooTools.


