检测溢出的菜单项并不总是能够正确计算

问题描述 投票:0回答:1

我正在尝试计算水平菜单是否有空间容纳所有菜单项,如果没有,则将溢出的项目包装在下拉列表中。

这是我所拥有的。它几乎有效,因为有时计算不正确。尝试调整窗口大小 - 您会看到类似这样的内容:

enter image description here

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>

我错过了什么? 预先感谢。

javascript css twitter-bootstrap
1个回答
0
投票

你的错误:

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>

© www.soinside.com 2019 - 2024. All rights reserved.