我仅基于HTML和CSS构建了一个简单的手风琴菜单。功能不错,但是问题是当您单击打开的手风琴时,它不会关闭。
我可以使用CSS还是需要JavaScript?
.middle a {
text-decoration: none;
}
.menu {
width: 100%;
overflow: hidden;
}
.item {
border-top: 1px solid #2980b9;
overflow: hidden;
}
.btn {
display: block;
padding: 16px 20px;
background: #3498db;
color: white;
position: relative;
}
.btn:before {
content: "";
position: absolute;
width: 14px;
height: 14px;
background: #3498db;
left: 20px;
bottom: -7px;
transform: rotate(45deg)
}
a i {
margin-right: 10px;
margin-left: 10px
}
.smenu {
background: white;
overflow: hidden;
transition: max-height 0.3s;
max-height: 0;
}
.smenu a {
display: block;
padding: 16px 26px;
font-size: 14px;
margin: 4px 0;
position: relative;
}
.smenu a:before {
content: "";
position: absolute;
width: 6px;
height: 100%;
background: #3498db;
left: 0;
top: 0;
transition: 0.3s;
opacity: 0;
}
a:hover:before {
opacity: 1;
}
.item:target .smenu {
max-height: 100%;
}
.item {
list-style-type: none
}
<div class="middle">
<div class="menu">
<li class="item" id="aboutus">
<a href="#aboutus" class="btn">About Us</a>
<div class="smenu">
<a href="#">1</a>
<a href="#">2</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#">6</a>
</div>
</li>
<li class="item" id="contactus">
<a href="#contactus" class="btn">Contact Us</a>
<div class="smenu">
<a><i class="fas fa-phone"></i>000-000-000</a>
<a><i class="fas fa-envelope-open"></i>Send Us An Email</a>
<a>ABCDEFG</a>
<a>P.O> Box 00000</a>
<a>New York, New York 000000</a>
<a><i class="fas fa-clock"></i>Monday - Friday: 9AM - 5PM ET</a>
<a><i class="fas fa-window-close"></i>Saturday-Sunday: Closed</a>
<a><i class="fas fa-desktop"></i>Online: 24/7</a>
</div>
</li>
<li class="item" id="sitelinks">
<a href="#sitelinks" class="btn">Site Links</a>
<div class="smenu">
<a href="#">1</a>
<a href="#">2</a>
<a href="#">3</a>
<a href="#">4t</a>
<a href="#">5</a>
<a href="#">6</a>
</div>
</li>
</div>
</div>
答案 0 :(得分:1)
打开一个手风琴面板是基于该面板li class="item"
是当前的 target (哈希)
.item:target .smenu {
max-height: 100%;
}
那么,关闭该面板的唯一方法是使<li>
不再是目标,再次单击该项目将不会执行该操作。您将不得不单击其他内容,或者使用javascript-因此“我可以使用CSS还是需要JavaScript?” 的基本答案是您需要javascript。 >
好消息是这是一个非常简单的javascript。在这里,将它包装在DOMContentLoaded
中,如果它位于从页面链接的自己的.js文件中,则需要这样做:
document.addEventListener("DOMContentLoaded", function(event) {
const items = document.querySelectorAll('.menu li.item');
for (let item of items) {
item.addEventListener('click', function(e) {
if ('#'+e.currentTarget.id === location.hash) {
e.preventDefault();
window.location.hash = '';
}
});
}
});
此查询(querySelectorAll)所有菜单项; li.item
内的.menu
个
然后,它循环遍历每个事件,并为“ click”事件附加事件侦听器。就是这样。
事件监听器本身也很简单。如果事件e
与当前位置相同,它将使用事件id
并获取当前点击目标的.item:target
。哈希表示您正在单击已打开的内容。 ..阻止默认操作(再次导航到哈希),然后清除哈希。
现在清除了哈希后,const items = document.querySelectorAll('.menu li.item');
for (let item of items) {
item.addEventListener('click', function(e) {
if ('#'+e.currentTarget.id === location.hash) {
e.preventDefault();
window.location.hash = '';
}
});
}
CSS选择器不匹配任何内容,因此关闭了先前打开的手风琴窗格。
制作代码片段时,该代码片段负责等待DOM准备就绪,因此我们将关闭该包装器。在这里,我要做的就是在自己的代码段中添加一些Javascript:
.middle a {
text-decoration: none;
}
.menu {
width: 100%;
overflow: hidden;
}
.item {
border-top: 1px solid #2980b9;
overflow: hidden;
}
.btn {
display: block;
padding: 16px 20px;
background: #3498db;
color: white;
position: relative;
}
.btn:before {
content: "";
position: absolute;
width: 14px;
height: 14px;
background: #3498db;
left: 20px;
bottom: -7px;
transform: rotate(45deg)
}
a i {
margin-right: 10px;
margin-left: 10px
}
.smenu {
background: white;
overflow: hidden;
transition: max-height 0.3s;
max-height: 0;
}
.smenu a {
display: block;
padding: 16px 26px;
font-size: 14px;
margin: 4px 0;
position: relative;
}
.smenu a:before {
content: "";
position: absolute;
width: 6px;
height: 100%;
background: #3498db;
left: 0;
top: 0;
transition: 0.3s;
opacity: 0;
}
a:hover:before {
opacity: 1;
}
.item:target .smenu {
max-height: 100%;
}
.item {
list-style-type: none
}
<div class="middle">
<div class="menu">
<li class="item" id="aboutus">
<a href="#aboutus" class="btn">About Us</a>
<div class="smenu">
<a href="#">1</a>
<a href="#">2</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#">6</a>
</div>
</li>
<li class="item" id="contactus">
<a href="#contactus" class="btn">Contact Us</a>
<div class="smenu">
<a><i class="fas fa-phone"></i>000-000-000</a>
<a><i class="fas fa-envelope-open"></i>Send Us An Email</a>
<a>ABCDEFG</a>
<a>P.O> Box 00000</a>
<a>New York, New York 000000</a>
<a><i class="fas fa-clock"></i>Monday - Friday: 9AM - 5PM ET</a>
<a><i class="fas fa-window-close"></i>Saturday-Sunday: Closed</a>
<a><i class="fas fa-desktop"></i>Online: 24/7</a>
</div>
</li>
<li class="item" id="sitelinks">
<a href="#sitelinks" class="btn">Site Links</a>
<div class="smenu">
<a href="#">1</a>
<a href="#">2</a>
<a href="#">3</a>
<a href="#">4t</a>
<a href="#">5</a>
<a href="#">6</a>
</div>
</li>
</div>
</div>
items
最后,由于除了循环之外,您不需要document.addEventListener("DOMContentLoaded", function(event) {
document.querySelectorAll('.menu li.item')
.forEach(element =>
element.addEventListener('click',
e => {
if ('#'+e.currentTarget.id === location.hash) {
e.preventDefault();
window.location.hash = '';
}
})
)
});
,因此您甚至不必将它们分配给变量。
这是进一步的最小化版本,用箭头函数替换了显式函数。
if ('#'+e.currentTarget.id === ...
{{1}}也可能会变成谓词,但我将其留给读者练习。