如何使addEventListener'click'在具有相同类的两个菜单项上工作
页面:https : //ensjotannklinikk.no/
这是一把小提琴
第一个名为“ Behandlinger ”的菜单项是用这个 JS(由biberman 提供)设置的,以使子菜单正确出现和缩回。
var submenu = document.querySelector('.behandlinger-meny');
var menuTrigger = document.querySelector('.behandlinger-item');
//javascript version of jQuery isChild()
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 = '55px';
});
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;
}
});
为什么这不适用于移动设备?我希望在单击菜单项 Behandlinger ( )时将子菜单 ( .behandlinger-meny) 高度设置为。它工作得很好,除了不在菜单项上单击 mobile。55px.behandlinger-item
意识到移动菜单有<nav>自己的,这可能会影响事件侦听器。我已经更新了下面的小提琴和简化结构以及核心问题。现在似乎非常接近一个简单的解决方案。
简化结构:
.behandlinger-meny {
height: 0;
transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
overflow: hidden;
}
<div id="wrapper">
<header>
<nav class="main-menu">
<ul>
<li class="behandlinger-item"><a href="#behandlinger">Behandlinger</a></li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a></li>
</ul>
</nav>
<nav class="mobile-main-menu">
<ul>
<li class="mobile-item behandlinger-item"><a href="#behandlinger">Behandlinger</a></li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a></li>
</ul>
</nav>
</header>
<section> <!-- Separated to follow page scroll -->
<div id="behandlinger"> <!-- Scroll to position on item click -->
<nav class="behandlinger-meny">
<script></script> <!-- Script in question -->
<ul>
<li><a>Sub item 1</a></li>
<li><a>Sub item 2</a></li>
<li><a>Sub item 3</a></li>
</ul>
</nav>
</div>
</section>
<main>
…
</main>
</div>
可运行版本:
var submenu = document.querySelector('.behandlinger-meny');
var menuTrigger = document.querySelector('.behandlinger-item');
//javascript version of jQuery isChild()
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 = '55px';
});
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;
}
});
.behandlinger-meny {
height: 0;
transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
overflow: hidden;
}
<div>
<header>
<nav>
<ul>
<li><a href="#behandlinger">Behandlinger</a></li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a></li>
</ul>
</nav>
<nav>
<ul>
<li><a href="#behandlinger">Behandlinger</a></li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a></li>
</ul>
</nav>
</header>
<section> <!-- Separated to follow page scroll -->
<div> <!-- Scroll to position on item click -->
<nav>
<script></script> <!-- Script in question -->
<ul>
<li><a>Sub item 1</a></li>
<li><a>Sub item 2</a></li>
<li><a>Sub item 3</a></li>
</ul>
</nav>
</div>
</section>
<main>
…
</main>
</div>
回答
由于您有两个触发器,并且您的事件侦听器仅附加到第一个querySelector触发器,而第二个触发器没有侦听器。
您可以使用querySelectorAllfor 循环中的事件侦听器并将其附加到每个选定的触发器。因为您想要过渡,所以必须使用“max-height”而不是“height”,因为过渡不适用于高度。
为了在点击其他地方(触发器或子菜单除外)时关闭子菜单,我创建了一个函数isRelated()来检查点击目标是触发器本身、子菜单还是两者的子菜单。
具有多个触发器的工作示例(下面的 jQuery 示例):
document.addEventListener('DOMContentLoaded', function() {
var submenu = document.querySelector('.behandlinger-meny');
var menuTrigger = document.querySelectorAll('.behandlinger-item');
function isRelated(item, parentSelector) {
while (item != undefined && item != null && item.tagName.toUpperCase() != 'BODY') {
parents = document.querySelectorAll(parentSelector);
for (i = 0; i < parents.length; i++) {
if (item == parents[i]) {
return true;
}
}
item = item.parentNode;
}
return false;
}
for (i = 0; i < menuTrigger.length; i++) {
menuTrigger[i].addEventListener('click', function() {
submenu.style.maxHeight = '1000px';
});
}
document.querySelector('body').addEventListener('click', function(e) {
if (!isRelated(e.target, '.behandlinger-item') && !isRelated(e.target, '.behandlinger-meny')) {
submenu.style.maxHeight = 0;
}
});
document.addEventListener('keyup', function(e) {
if (e.key == 'Escape') {
submenu.style.maxHeight = 0;
}
});
});
header {
display: flex;
}
.behandlinger-meny {
max-height: 0;
width: 150px;
background-color: #ddd;
transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
overflow: hidden;
}
header {
display: flex;
}
.behandlinger-meny {
max-height: 0;
width: 150px;
background-color: #ddd;
transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
overflow: hidden;
}
<div>
<header>
<nav>
<ul>
<li><a href="#behandlinger">Behandlinger</a></li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a></li>
</ul>
</nav>
<nav>
<ul>
<li><a href="#behandlinger">Behandlinger</a></li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a></li>
</ul>
</nav>
</header>
<section>
<div>
<nav>
<ul>
<li><a>Sub item 1</a></li>
<li><a>Sub item 2</a></li>
<li><a>Sub item 3</a></li>
</ul>
</nav>
</div>
</section>
<main>
…
</main>
</div>
jQuery 示例:
$().ready(function() {
var submenu = $('.behandlinger-meny');
$('.behandlinger-item').on('click', function() {
submenu.css('maxHeight', '1000px');
});
$('body').on('click', function(e) {
if (!$(e.target).parents().is('.behandlinger-item')
&& !$(e.target).parents().is('.behandlinger-meny')) {
submenu.css('maxHeight', 0);
}
});
$(document).on('keyup', function(e) {
if (e.key == 'Escape') {
submenu.css('maxHeight', 0);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<header>
<nav>
<ul>
<li><a href="#behandlinger">Behandlinger</a></li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a></li>
</ul>
</nav>
<nav>
<ul>
<li><a href="#behandlinger">Behandlinger</a></li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a></li>
</ul>
</nav>
</header>
<section>
<div>
<nav>
<ul>
<li><a>Sub item 1</a></li>
<li><a>Sub item 2</a></li>
<li><a>Sub item 3</a></li>
</ul>
</nav>
</div>
</section>
<main>
…
</main>
</div>
THE END
二维码