html - 单击菜单项时如何影响其他元素
问题描述
我创建了一个自定义非粘性子菜单,我希望在单击某个菜单项时显示该子菜单。单击时我将其滚动到位置,并且我决定要使用 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:在https://ensjotannklinikk.no/forside-wip/实施了@biberman 建议的变体。以下是现场版的不同之处:
"Behandlinger" = 有问题的菜单项
.behandlinger-meny
代替#submenu
.behandlinger-item
代替.submenu-trigger
55px
而不是auto
, 以保留 CSS 过渡
document.querySelector('.behandlinger-item').addEventListener('click', function() {
var submenu = document.querySelector('.behandlinger-meny');
submenu.style.height = '55px';
});
真的很接近,感谢@biberman。
唯一缺少的是
让它在每次点击时保持打开状态(而不是打开和关闭)。想通了自己。单击其他任何位置但@biberman 再次触发时关闭(返回到高度 0。.behandlinger-meny
).behandlinger-item
此修复不适用于移动设备。新问题。
非常感谢,堆栈溢出!
解决方案
这可以通过 js 轻松完成(在脚本标签或单独的 js 文件中)。您只需要一个用于“单击”的事件侦听器和一个用于更改高度的小函数:
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>
推荐阅读
- r - 如何在 R 中没有循环的情况下快速访问列表列表中的元素?(谷歌方式包)
- snowflake-cloud-data-platform - Snowflake-如何获取现有表的sql脚本
- java - 如何在 JAR 文件中的 Jetty 服务器中启用 JSP?
- postgresql - 使用 kubernetes 集群作为一种路由器从 Tableau 访问 Postgres 主机
- java - 类型不匹配:无法从 MobileElement 转换为 List
- regex - 带条件的去 RE2 正则表达式重复组
- python - 识别时间序列、股票数据中的熊市
- python - 列表中的维护列表,同时过滤掉值
- python - 键盘快捷键在 Selenium(Python、Firefox)中不起作用 [不仅仅是新标签]
- discord.py - 在 discord.py 中,我想修复 ERROR 'Unreachable code'