Горизонтальное stretch меню
Есть горизонтальное меню и кнопка more.
Если пункты меню не вмещаются во всю доступную ширину, то остальные пункты должны "прятаться" в dropdown меню. При клике на кнопку, раскрывается меню с "оставшимися пунктами.
Все это должно работать и при ресайзе и при загрузке.
Код:
function adaptMenu() {
var $category = $('.category'),
$categoryList = $category.find('.category-list'),
$categoryMore = $category.find('.category-more'),
$categoryMoreDD = $categoryMore.closest('.dropdown'),
$categoryMoreMenu = $categoryMoreDD.find('.dropdown-menu'),
$categoryItems = $categoryList.find('.category-item');
var $visible = [],
$hidden = [];
$categoryItems.hide();
var $width = $categoryList.width();
$categoryItems.show();
var $total = 0;
$categoryItems.each(function() {
var item = $(this);
item.css({
'width': 'auto'
});
$total += item.width();
if ($total < $width) {
$visible.push(item);
} else {
$hidden.push(item);
}
});
if ($hidden.length > 0) {
$categoryMoreMenu.append($hidden);
} else {
$categoryMoreMenu.find('li').hide();
}
}
$(window).on('load', function() {
adaptMenu();
});
$(window).on('resize', function() {
adaptMenu();
});
adaptMenu();
.category-list {
overflow: hidden;
}
.dropdown .category-item {
width: 100%;
margin: 0 !important;
}
.dropdown .cat {
width: 100%;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<div class="category">
<div class="container-fluid">
<div class="row">
<div class="col-9">
<ul class="category-list list-unstyled d-flex w-100">
<li class="category-item px-2"><a href="" class="cat btn btn-primary">1</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">2</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">3</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">4</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">5</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">6</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">7</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">8</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">9</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">10</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">11</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">12</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">13</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">14</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">15</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">16</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">17</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">18</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">19</a></li>
<li class="category-item px-2"><a href="" class="cat btn btn-primary">20</a></li>
</ul>
</div>
<div class="col-3">
<div class="dropdown">
<button class="category-more w-100 btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
More
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
</div>
</div>
</div>
</div>
</div>
</div>
Вопрос: как реализовать отображение\скрытие пунктов меню в dropdown меню, которые не вмещаются в доступную видимую ширину меню и при загрузке и при ресайзе?
Ответы (1 шт):
Автор решения: Sevastopol'
→ Ссылка
Есть у меня одно интересное решение. Автора правда не знаю, но ему спасибо, отлично получилось, и ничего больше делать не нужно. Поделюсь с вами:
var $nav = $('.nav');
var $btn = $('.nav button');
var $vlinks = $('.nav .visible-links');
var $hlinks = $('.nav .hidden-links');
var breaks = [];
function updateNav() {
var availableSpace = $btn.hasClass('hidden') ? $nav.width() : $nav.width() - $btn.width() - 30;
if ($vlinks.width() > availableSpace) {
breaks.push($vlinks.width());
$vlinks.children().last().prependTo($hlinks);
if ($btn.hasClass('hidden')) {
$btn.removeClass('hidden');
}
} else {
if (availableSpace > breaks[breaks.length - 1]) {
$hlinks.children().first().appendTo($vlinks);
breaks.pop();
}
if (breaks.length < 1) {
$btn.addClass('hidden');
$hlinks.addClass('hidden');
}
}
$btn.attr("count", breaks.length);
if ($vlinks.width() > availableSpace) {
updateNav();
}
}
$(window).resize(function() {
updateNav();
});
$btn.on('click', function() {
$hlinks.toggleClass('hidden');
});
updateNav();
* {
margin: 0;
padding: 0;
}
body {
margin: 50px 25px;
}
.nav {
position: relative;
min-width: 250px;
background: gold;
border-top: 1px solid red;
border-bottom: 1px solid red;
}
.nav a {
display: block;
padding: 10px 20px;
background: gold;
font-size: 18px;
color: black;
text-decoration: none;
}
.nav a:hover {
color: red;
}
.nav button {
position: absolute;
height: 100%;
right: 0;
padding: 0 15px;
border: 0;
outline: none;
background-color: red;
color: #fff;
cursor: pointer;
}
.nav button:hover {
background-color: indianred;
}
.nav button::after {
content: attr(count);
position: absolute;
width: 25px;
height: 25px;
left: -16px;
top: 7px;
text-align: center;
background-color: red;
color: #fff;
font-size: 14px;
line-height: 25px;
border-radius: 50%;
border: 2px solid #fff;
font-weight: bold;
}
.nav button:hover::after {
transform: scale(1.05);
}
.nav .hamburger {
position: relative;
width: 32px;
height: 4px;
background: #fff;
margin: auto;
}
.nav .hamburger:before,
.nav .hamburger:after {
content: '';
position: absolute;
left: 0;
width: 32px;
height: 4px;
background: #fff;
}
.nav .hamburger:before {
top: -8px;
}
.nav .hamburger:after {
bottom: -8px;
}
.nav .visible-links {
display: inline-table;
}
.nav .visible-links li {
display: table-cell;
border-left: 1px solid red;
}
.nav .hidden-links {
position: absolute;
right: 0px;
top: 100%;
border-left: 1px solid red;
border-right: 1px solid red;
border-bottom: 1px solid red;
}
.nav .hidden-links li {
display: block;
border-top: 1px solid red;
}
.nav .visible-links li:first-child {
font-weight: bold;
}
.nav .visible-links li:first-child a {
color: red !important;
}
.nav .hidden {
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class='nav'>
<button><div class="hamburger"></div></button>
<ul class='visible-links'>
<li><a href='#'>Главная</a></li>
<li><a href='#'>Проекты</a></li>
<li><a href='#'>Заказы</a></li>
<li><a href='#'>Выполненные работы</a></li>
<li><a href='#'>Отзывы</a></li>
<li><a href='#'>Наши планы</a></li>
<li><a href='#'>Инвесторы</a></li>
<li><a href='#'>Контакты</a></li>
</ul>
<ul class='hidden-links hidden'></ul>
</nav>