单击菜单项时如何影响其他元素

How to affect other elements when menu item is clicked

我创建了一个自定义的非粘性子菜单,我希望在单击某个菜单项时显示该子菜单。单击时我将它滚动到位置,我决定要使用 height 属性控制可见性。使用 CSS 执行此操作的正确方法是什么?


这也是我的第一个问题。我很欣赏关于提出更好问题的提示。

结构看起来像这样

#submenu {
  height: 0;
  overflow: hidden;
}

.submenu-trigger:focus~#submenu {
  height: 134px !important;
}
<div id="wrapper">
  <header>
    <nav>
      <ul>
        <li><a>Item 1</a></li>
        <li><a>Item 2</a></li>
        <li><a class="submenu-trigger" href="#submenu">Item 3</a></li>
        <li><a>Item 4</a></li>
      </ul>
    </nav>
  </header>

  <!-- Placed outside to follow page scroll -->
  <section>
    <div id="submenu">
      <nav>
        <ul>
          <li><a>Item 1</a></li>
          <li><a>Item 2</a></li>
          <li><a>Item 3</a></li>
        </ul>
      </nav>
    </div>
  </section>

  <main>
    …
  </main>
</div>


编辑:CSS 似乎无法做到这一点。当主菜单项不再处于焦点状态时,如何使用 JS 使子菜单收回?

编辑 2:实现了 @ at https://ensjotannklinikk.no/forside-wip/ 的变体。以下是实时版本的不同之处:

    document.querySelector('.behandlinger-item').addEventListener('click', function() {
            var submenu = document.querySelector('.behandlinger-meny');
            submenu.style.height = '55px';
    });

真的很接近,感谢@biberman。

唯一缺少的是

非常感谢,Stack Overflow!

这可以使用 js 轻松完成(在脚本标记或单独的 js 文件中)。您只需要 'click' 的事件侦听器和更改高度的小函数:

document.querySelector('.submenu-trigger').addEventListener('click', function() {
    var submenu = document.querySelector('#submenu');
    submenu.style.height = submenu.style.height == 'auto' ? 0 : 'auto';
});
#submenu {
    height: 0;
    overflow: hidden;
}

.submenu-trigger:focus ~ #submenu {
    height: 134px !important;
}
<div id="wrapper">
  <header>
    <nav>
      <ul>
        <li><a>Item 1</a></li>
        <li><a>Item 2</a></li>
        <li><a class="submenu-trigger" href="#submenu">Item 3</a></li>
        <li><a>Item 4</a></li>
      </ul>
    </nav>
  </header>
  
  <section>
    <div id="submenu">
      <nav>
        <ul>
          <li><a>Item 1</a></li>
          <li><a>Item 2</a></li>
          <li><a>Item 3</a></li>
        </ul>
      </nav>
    </div>
  </section>
  
  <main>
    …
  </main>
</div>


如果您在没有额外 javascript 的情况下搜索解决方案,也许您可​​以将其减少到最低限度并内联执行。 (最好不要混合 html 结构和程序代码,但它有效):

#submenu {
    height: 0;
    overflow: hidden;
}
<div id="wrapper">
  <header>
    <nav>
      <ul>
        <li><a>Item 1</a></li>
        <li><a>Item 2</a></li>
        <li><a class="submenu-trigger" href="#submenu" onclick="document.querySelector('#submenu').style.height = (document.querySelector('#submenu').style.height == 'auto') ? '0' : 'auto';">Item 3</a></li>
        <li><a>Item 4</a></li>
      </ul>
    </nav>
  </header>
  
  <section>
    <div id="submenu">
      <nav>
        <ul>
          <li><a>Item 1</a></li>
          <li><a>Item 2</a></li>
          <li><a>Item 3</a></li>
        </ul>
      </nav>
    </div>
  </section>
  
  <main>
    …
  </main>
</div>


如果您想在单击其他地方(不是 .submenu-trigger 也不是 #submenu)或按下 'Esc' 时关闭菜单,那么您还需要两个事件侦听器。但这不是内联的:

var submenu = document.querySelector('#submenu');
var menuTrigger = document.querySelector('.submenu-trigger');

function isChild(item, parentItem) {
    while (item != undefined && item != null && item.tagName.toUpperCase() != 'BODY'){
        if (item == parentItem){
            return true;
        }
        item = item.parentNode;
    }
    return false;
}

menuTrigger.addEventListener('click', function() {
    submenu.style.height = 'auto';
});

document.querySelector('body').addEventListener('click', function(e) {
    if ( !isChild(e.target, menuTrigger) && !isChild(e.target, submenu) ) {
        submenu.style.height = 0;
    }
});

document.addEventListener('keyup', function(e) {
    if ( e.key == 'Escape' ) {
        submenu.style.height = 0;
    }
});
#submenu {
    height: 0;
    width: 100px;
    background-color: #ddd;
    overflow: hidden;
}
<div id="wrapper">
    <header>
        <nav>
            <ul>
                <li><a>Item 1</a></li>
                <li><a>Item 2</a></li>
                <li><a class="submenu-trigger" href="#submenu">Item 3</a></li>
                <li><a>Item 4</a></li>
            </ul>
        </nav>
    </header>

    <section>
    <div id="submenu">
        <nav>
            <ul>
                <li><a>Item 1</a></li>
                <li><a>Item 2</a></li>
                <li><a>Item 3</a></li>
            </ul>
        </nav>
    </div>
    </section>

    <main>
        ...
    </main>
</div>


jQuery 示例:

var submenu = $('#submenu');

$('.submenu-trigger').on('click', function() {
  submenu.css('height', 'auto');
});

$('body').on('click', function(e) {
  if (!$(e.target).is('.submenu-trigger') &&
    !$(e.target).parents().is('#submenu')) {
    submenu.css('height', 0);
  }
});

$(document).on('keyup', function(e) {
  if (e.key == 'Escape') {
    submenu.css('height', 0);
  }
});
#submenu {
  height: 0;
  width: 100px;
  background-color: #ddd;
  overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="wrapper">
  <header>
    <nav>
      <ul>
        <li><a>Item 1</a></li>
        <li><a>Item 2</a></li>
        <li><a class="submenu-trigger" href="#submenu">Item 3</a></li>
        <li><a>Item 4</a></li>
      </ul>
    </nav>
  </header>

  <section>
    <div id="submenu">
      <nav>
        <ul>
          <li><a>Item 1</a></li>
          <li><a>Item 2</a></li>
          <li><a>Item 3</a></li>
        </ul>
      </nav>
    </div>
  </section>

  <main>
    ...
  </main>
</div>