我正在尝试计算水平菜单是否有空间容纳所有菜单项,如果没有,则将溢出的项目包装在下拉列表中。
这是我所拥有的。它几乎有效,因为有时计算不正确。尝试调整窗口大小 - 您会看到类似这样的内容:
const nav = document.querySelector(".navbar");
const contentBar = nav.querySelector(".navbar-nav");
const navItems = document.querySelectorAll(".navbar-nav > li:not(.grouped)");
const allItems = contentBar.querySelectorAll('li');
const dropdown = nav.querySelector(".grouped-content");
const more = nav.querySelector(".grouped");
const update = () => {
// Show all items for exact calculation
allItems.forEach((item) => {
item.classList.remove('d-none');
});
let avaliableWidth = nav.offsetWidth;
let stopWidth = more.offsetWidth;
let subitems = [];
dropdown.innerHTML = "";
navItems.forEach((item, i) => {
// Calculate if menu items are wider than navbar
if (avaliableWidth > stopWidth + item.offsetWidth) {
stopWidth += item.offsetWidth;
} else {
// Not enough space
let li = document.createElement("li");
li.innerHTML = item.innerHTML;
// Append overflowing menu items to dropdown
dropdown.appendChild(li);
// Hide items that won't fit in menu
item.classList.add('d-none');
// Count items in dropdown
subitems.push(i);
}
})
// Hide "More" item if it has no children
if (!subitems.length) {
more.classList.add('d-none');
}
}
update();
window.addEventListener("resize", update);
.nav-link {
white-space: nowrap;
max-width: 100px;
text-overflow: ellipsis;
overflow: hidden;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="container">
<nav class="navbar navbar-expand-sm">
<ul class="navbar-nav">
<li class="nav-item"><a href="#" class="nav-link">Item 1</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 22</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 333</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 4444</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 5555555</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 66</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 7777777777777</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 8</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 999999</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 10101010</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 1111</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 12121212</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 131313131313</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 1414</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 15</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 16161616</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 1717</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 18181818181818</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 191919</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 20</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 212121</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 2222</a></li>
<li class="nav-item dropdown grouped">
<a href="#" class="nav-link dropdown-toggle" aria-haspopup="true" aria-expanded="false" role="button" data-bs-toggle="dropdown" data-bs-display="static" data-bs-auto-close="outside">More</a>
<ul class="dropdown-menu grouped-content"></ul>
</li>
</ul>
</nav>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
我错过了什么? 预先感谢。
你的错误:
if (avaliableWidth > stopWidth + item.offsetWidth) {
更改为(看括号)
if (avaliableWidth > (stopWidth + item.offsetWidth)) {
这都是关于运算符优先级
最干净的方法来做到这一点...
(这也适用于引导媒体查询)
const
nav = document.querySelector('.navbar') // nav
, contentBar = nav.querySelector('.navbar-nav') // nav > ul
, moreGroup = nav.querySelector('.navbar-nav > li.grouped')
, navItems = [...nav.querySelectorAll('.navbar-nav > li:not(.grouped)')]
, dropdown = moreGroup.querySelector('ul.grouped-content')
;
sizingNav();
window.addEventListener('resize', sizingNav);
function sizingNav()
{
let avaliableWidth = nav.offsetWidth;
dropdown.innerHTML = '';
moreGroup.classList.add('d-none');
navItems.forEach( item => item.classList.remove('d-none') );
for (let i = navItems.length; i-- > 0;)
{
if ( contentBar.offsetWidth > avaliableWidth )
{
let li = dropdown.appendChild(document.createElement('li'));
li.innerHTML = navItems[i].innerHTML;
navItems[i].classList.add('d-none');
moreGroup.classList.remove('d-none');
}
else break;
}
}
.nav-link {
white-space : nowrap;
max-width : 100px;
text-overflow : ellipsis;
overflow : hidden;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous" defer></script>
<div class="container">
<nav class="navbar navbar-expand-sm pinked">
<ul class="navbar-nav">
<li class="nav-item"><a href="#" class="nav-link">Item 1</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 2-2</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 3-33</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 4-444</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 5-555555</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 6-6</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 7-777777777777</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 8</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 9-99999</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 10+101010</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 11+11</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 12+121212</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 13+1313131313</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 14+14</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 15+</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 16+161616</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 17+17</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 18+181818181818</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 19+1919</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 20+</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 21+2121</a></li>
<li class="nav-item"><a href="#" class="nav-link">Item 22+22</a></li>
<li class="nav-item dropdown grouped">
<a href="#" class="nav-link dropdown-toggle" aria-haspopup="true" aria-expanded="false" role="button" data-bs-toggle="dropdown" data-bs-display="static" data-bs-auto-close="outside">More</a>
<ul class="grouped-content"></ul>
</li>
</ul>
</nav>
</div>