jQuery как сделать, чтобы пункты меню заполнили все пространство по-ширине?
В этом посте мы будем корректировать ширину пунктов горизонтального меню, чтобы расположить их от края до края.
Создадим простое горизонтальное меню, без отступов между элементами.
Все отступы и ширину самих пунктов мы будем рассчитывать с помощью jQuery функции, которую напишем чуть позже, т.е. меню изначально выглядит так:
Вот html код меню:
<div id="wrapper"> <ul class="nav"> <li><a href="#">Пункт №1</a></li> <li><a href="#">Пункт №2</a></li> <li><a href="#">Пункт №3</a></li> <li><a href="#">Пункт №4</a></li> <li><a href="#">Пункт №5</a></li> <li><a href="#">Пункт №6</a></li> </ul> </div>
CSS стили демо примера:
#wrapper { overflow: hidden; width: 900px; padding: 50px 30px; margin: 100px auto; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); background: #369; } .nav { display: block; margin: 0; padding: 0; list-style-type: none; } .nav li { float: left; } .nav li a { display: block; padding: 5px 0; font-family: Arial, Verdana, sans-serif; color: #dedede; text-decoration: none; } .nav li a:hover { color: #FFF; text-shadow: 1px 1px 3px rgba(0,0,0,0.55); }
Создание jQuery функции по равномерному распределению пунктов меню
Для того чтобы распределить пункты меню от края до края, необходимо знать некоторые входные параметры.
Основной параметр - это ширина меню. Этот параметр мы будем задавать в качестве аргумента для нашей функции.
Логика расчетов:
- Узнать суммарную ширину всех пунктов меню.
- Узнать насколько ширина меню больше чем суммарная ширина всех пунктов, назовем эту разнице дельта.
- Теперь дельту, нужно равномерно распределить между пунктами меню в качестве отступов (padding-left), при этом у первого пункта меню он будет равен нулю.
На первый взгляд все просто, но тут есть несколько подводных камней в этой задаче.
1. Нужно узнать актуальную (не округленную) ширину каждого пункта меню
Узнать реальную ширину с дробной частью, можно следующим образом:
$(this)[0].getBoundingClientRect().width
2. После того как мы узнаем реальную ширину элемента мы ее округлим и тоже самое сделаем с отступами между элементами, чтобы быть уверенными, что у нас будет одинаковое значение ширины элементов и их отступов во всех браузерах.
Вот так выглядит весь код jQuery функции без комментариев:
$(document).ready(function(){ $.fn.fullWideMenu = function(width) { var $menu = $(this), $menuItems = $('>li', $menu), qty = $menuItems.length, itemWidth = 0, mWidth = 0, delta = 0, decimal = 0, floatPart = 0; $menuItems.each(function(){ itemWidth = Math.ceil( $(this)[0].getBoundingClientRect().width ); console.log($(this)[0].getBoundingClientRect().width+" = "+itemWidth); $(this).width( itemWidth ); mWidth += itemWidth; }); delta = (width - mWidth)/(qty - 1); decimal = delta % 1; delta = Math.floor( delta ); floatPart = Math.floor( decimal*(qty - 1) ); $menuItems.css({paddingLeft: delta+'px'}); $menuItems.first().css({paddingLeft: 0}); $menuItems.last().css({paddingLeft: (delta + floatPart)+'px'}); } $('.nav').fullWideMenu(900); });
Вот этот же код, но с комментариями:
$(document).ready(function(){ //функция имеет параметр width - ширина меню $.fn.fullWideMenu = function(width) { var $menu = $(this), //запишем элемент которому применена наша функция $menuItems = $('>li', $menu), //элементы меню qty = $menuItems.length, //кол-во элементов меню itemWidth = 0, //ширина пункта меню mWidth = 0, //ширина всех пунктов меню delta = 0, //отступ между меню decimal = 0, //дробная часть отступа floatPart = 0; //суммарная дробная часть отступа между всеми пунктами, округленная к ближайшему меньшему целому значению //обходим каждый пункт меню $menuItems.each(function(){ itemWidth = Math.ceil( $(this)[0].getBoundingClientRect().width ); //узнаем реальную ширину пункта и округляем ее к ближайшему большему целому числу $(this).width( itemWidth ); //задаем округленную ширину текущему пункту mWidth += itemWidth; //подсчитываем суммарную ширину всех пунктов }); delta = (width - mWidth)/(qty - 1); //узнаем значение отступа между пунктами меню decimal = delta % 1; //берем дробную часть у отступа delta = Math.floor( delta ); //округляем отступ к ближайшему меньшему целому числу floatPart = Math.floor( decimal*(qty - 1) ); //суммарное округленное значение дробных частей отступа между пунктами $menuItems.css({paddingLeft: delta+'px'}); //всем пунктам меню задаем отступ слева $menuItems.first().css({paddingLeft: 0}); //у первого пункта убираем его, т.к. отступ должен быть только между пунктами меню $menuItems.last().css({paddingLeft: (delta + floatPart)+'px'}); //последнему пункту к отступу суммируем дробную часть всех отступов } //применяем функцию к нашему меню со значение ширины = 900 пикселов $('.nav').fullWideMenu(900); });
Вот что у нас получилось в после применения функции:
Если у вас остались вопросы, пишите их в комментариях к посту 😉
Рубрика: Как сделать?
Зачем так усложнять жизнь?
nav1
nav2
nav3
nav4
nav5
#space-around{
display: flex;
justify-content: space-around;
}
К сожалению мы живем не в идеальном мире, откройте ваш код в ИЕ8 😉
Спасибо за Ваш комментарий, более чем уверен что он будет многим полезен.
Статья 2014го, ваш комментарий 2016го
Все верно ))