Растягиваем основное меню на ширину контента

Главные вкладки

Аватар пользователя olk olk 2 апреля 2013 в 14:06

Репост с моего блога Растягиваем основное меню на ширину контента

Иногда необходимо "растянуть" основное горизонтальное меню сайта на всю ширину основного контента.
Предлагаю решение при помощи небольшого javascript-а.
1. Для начала нам надо немного преобразовать вывод меню, для того что бы в дальнейшем можно было его легче обработать скриптом (нам необходимо ввести дополнительный признак "глубины" пункта меню, что бы обработать только самый верхний уровень меню.
Для этого в своей теме в файле template.php создаем (или переопределяем) функцию
ВАША_ТЕМА_menu_link__main_menu(array $variables)
У меня получилась функция со следующим содержанием
/*
* Здесь olkgrid - имя моей темы
*/
function olkgrid_menu_link__main_menu(array $variables) {
$element = $variables['element'];
$sub_menu = '';
$element['#attributes']['class'][] = 'menu-' . $element['#original_link']['mlid'];
$element['#attributes']['class'][] = 'depth-' . $element['#original_link']['depth'];

static $item_cnt = 0;
if($element['#original_link']['depth']>1){
$element['#attributes']['class'][] = 'item-'.(++$item_cnt);
}
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
$element['#attributes']['class'][] = 'dropdown';
}
$output = l($element['#title'] , $element['#href'], $element['#localized_options']);
return '

  • ' . $output . $sub_menu . ''."\n";
    }
    ?>

    В данном коде нам важно, что для каждого уровня меню мы присваиваем класс depth-N - соответствующий уровню пункта меню.

    Далее сам скрипт растягивания, мы предполагаем, что меню построено (в плане темизации) корректно, и вся ширина пункта меню задается непосредственно для ссылки (т.е. тэг )

    Пояснения к скрипту
    navigation-content - это id контейнера меню по ширине равный ширине контента
    остальное в комментариях скрипта

    /**
     *  file olkgrid.js
     */

    (function ($) {

        Drupal.behaviors.StretchMainMenu = {
            attach: function (context, settings) {
                // получим ширину контйнера
                var n_width=parseInt($('#navigation-content').width());
                var cnt=0;  // счетчик пунктов меню 1-го уровня
                var w = 0;  // в этой переменной будем считать ширину занимаемую меню
                var delta=0;
                // пройдемся по всем пунктам меню 1-го уровня
                $('#navigation-content li.depth-1 > a').each(function(index) {
                        // вычисляем ширину текущего меню и количество пунктов меню 1-го уровня
                        w += parseInt($(this).width())+parseInt($(this).css("padding-left"))+ parseInt($(this).css("padding-right"))+parseInt($(this).css("margin-left"))+ parseInt($(this).css("margin-right"))+parseInt($(this).css("border-left-width"))+parseInt($(this).css("border-right-width"));
                        cnt++;
                }
                )
                // если ширина текущего меню меньше ширины контейнера то будем растягивать
                if(n_width>w) {
                      // дельта если не делиться на ровно
                      delta = (n_width-w) % (cnt);
                     // сколько добавить к каждому пункту
                    var add_padding = (n_width-w-delta) / (cnt);
                     // добавляем отступ (padding) к каждому пункту меню
                $('#navigation-content li.depth-1 > a').each(function(index) {
                    var cur_padding_left=parseInt($(this).css("padding-left"))+parseInt(add_padding/2);
                    var cur_padding_right=parseInt($(this).css("padding-right"))+parseInt(add_padding/2)+(add_padding % 2);
                    $(this).css("padding-left",cur_padding_left+'px');
                    $(this).css("padding-right",cur_padding_right+'px');
                }
                )
                    // если есть дельта, то добавим к первому и последнему пункту соответствующий отступ
                    if(delta>0) {
                    var first_padding_left=parseInt($('#navigation-content li.first.depth-1 > a').css("padding-left"))+parseInt(delta/2);
                    var last_padding_right=parseInt($('#navigation-content li.last.depth-1 > a').css("padding-right"))+parseInt(delta/2)+(delta % 2);
                    $('#navigation-content li.first.depth-1 > a').css("padding-left",first_padding_left+'px');
                    $('#navigation-content li.first.depth-1 > a').css("padding-right",last_padding_right+'px');
                     }

                }

            }
        };

    })(jQuery);

    Меню до обработки
    До

    Меню после обработки
    После