[英]Is there a simpler way to make this expandable menu?
我想制作一个包含三个或更多项目的可扩展菜单。 单击其中一项时,它会展开以显示<ul>
,该<ul>
display: hidden
在其下方。
此外,我希望它的工作方式是:如果该菜单上的一个项目已经被展开,如果我单击其他任何一个项目,则在展开第二个项目之前,它会撤消第一个项目的内容(一个项目点击)。
我的代码是这个 。 我必须为在那里的三个项目分别定义一个不同的toggle
功能,以及一个额外的switchAll
函数,以便在继续扩展新项目之前隐藏任何扩展项目。
但是,该解决方案似乎并不是最好的。
有没有更好的方法来定义可以处理所有三个项目的函数? 为此,我需要它获得之前单击的项目,以便它可以了解是否扩展了哪些项目,以及相应地采取了哪些措施。
我猜这只能用两个函数来完成,但是我似乎无法弄清楚该怎么做。
另外,我想用Javascript而不是jQuery来实现。
相关代码如下:
HTML:
<ul>
<li><a href="#" onclick="toggle();">one</a>
<ul id="menu">
<li>sacd</li>
<li>safsdf</li>
</ul>
</li>
<li><a href="#" onclick="toggle1();">two</a>
<ul id="menu2">
<li>jlkfd</li>
<li>ljsdf</li>
</ul>
</li>
<li><a href="#" onclick="toggle2();">three</a>
<ul id="menu3">
<li>sfsdvbg gb</li>
<li>asdavffds</li>
</ul>
</li>
</ul>
CSS:
#menu {
display: none;
}
#menu2 {
display : none;
}
#menu3 {
display : none;
}
JS:
var hidden = true;
var hidden2 = true;
var hidden3 = true;
function switchAll(other1, other2) {
other1.style.display = "none";
other2.style.display = "none";
hidden = true;
hidden2 = true;
hidden3 = true;
};
function toggle() {
var menu = document.getElementById("menu");
var menu2 = document.getElementById("menu2");
var menu3 = document.getElementById("menu3");
if(hidden) {
switchAll(menu2, menu3);
menu.style.display = "block";
hidden = false;
} else {
menu.style.display = "none";
hidden = true;
};
};
function toggle1() {
var menu = document.getElementById("menu");
var menu2 = document.getElementById("menu2");
var menu3 = document.getElementById("menu3");
if(hidden2) {
switchAll(menu, menu3);
menu2.style.display = "block";
hidden2 = false;
} else {
menu2.style.display = "none";
hidden2 = true;
};
};
function toggle2() {
var menu = document.getElementById("menu");
var menu2 = document.getElementById("menu2");
var menu3 = document.getElementById("menu3");
if(hidden3) {
switchAll(menu, menu2);
menu3.style.display = "block";
hidden3 = false;
} else {
menu3.style.display = "none";
hidden3 = true;
};
};
如果我的第一个答案是复杂,这里是没有动画和js的css only替代方案。
HTML
<ul class="box">
<li id="a"><a href="#a">one</a>
<ul>
<li>sacd</li>
<li>safsdf</li>
</ul>
</li>
<li id="b"><a href="#b">two</a>
<ul>
<li>jlkfd</li>
<li>ljsdf</li>
</ul>
</li>
<li id="c"><a href="#c">three</a>
<ul>
<li>sfsdvbg gb</li>
<li>asdavffds</li>
</ul>
</li>
</ul>
CSS
.box>li>ul{
display: none;
}
.box>li:target>ul{
display:block;
}
DEMO
没有JavaScript ...
将当前展开的项目存储在变量中。
var current = null;
function toggle(element) {
if(current === null) {
// Show 'element'
current = element;
}
else if(element === current) {
// Hide 'current'
current = null;
}
else {
// Show 'element' and hide 'current'
current = element;
}
}
我的JSFiddle在这里: http : //jsfiddle.net/naokiota/38W8X/12/
这是简化功能的示例:
HTML
<ul>
<li><a href="#" onclick="toggle(1);" >one</a>
<ul class="submenu">
<li>sacd</li>
<li>safsdf</li>
</ul>
</li>
<li><a href="#" onclick="toggle(2);" >two</a>
<ul class="submenu">
<li>jlkfd</li>
<li>ljsdf</li>
</ul>
</li>
<li><a href="#" onclick="toggle(3);" >three</a>
<ul class="submenu">
<li>sfsdvbg gb</li>
<li>asdavffds</li>
</ul>
</li>
</ul>
JavaScript的
function toggle(n) {
var menus = document.getElementsByClassName("submenu");
for(var i=0;i<menus.length;i++){
if((i == (n-1)) && (menus[i].style.display != "block")){
menus[i].style.display = "block";
}else{
menus[i].style.display = "none";
}
}
};
CSS
.submenu {
display: none;
}
希望这可以帮助。
是的,有一种更简单/(更生动有趣的动画)的方式来编写类似的东西。
accordion
类来添加多个手风琴 我前段时间编写了这段代码,并对它进行了优化和压缩。
给我一些时间,我发布一个更具可读性的代码...因为我向您展示了最终版本之一。
这是手风琴。
function h(e){
var p='parentNode',a=e.target,b=a[p],f=48,u='px',y=b.firstChild==a?b[p]:y;
!y.c||(y.c==b||(y.c.style.height=f+u,y.c.x=f)),
y.c=y.c==b?null:b,
a!=b.firstChild||(b.x=b.x>f?f:(f+b.childNodes[1].offsetHeight),
b.style.height=b.x+u)
}
document.getElementById('container').addEventListener('click',h,false);
DEMO
这是另一个版本
function handler(e){
e=e||window.event;
var target=e.target||e.srcElement;
var action=target.dataset['action']||'no action';
!(action=='toggle')||(target.childNodes[1].classList.toggle('show'));
!target.dataset['url']||alert(target.dataset['url']);
}
var firstUL=document.getElementsByTagName('ul')[0];
firstUL.addEventListener('click',handler,false);
可读版本(略有不同)
这基本上是一个手风琴插件
(function(D){
function acsf(e){
var a=e.target.parentNode,h;
if(a.parentNode==this&&a.firstChild==e.target){
if(this.c==a){
this.c.style.height='';
delete this.c
}else{
if(this.c){
this.c.style.height=''
}
this.c=a;
this.c.style.height=(a.firstChild.offsetHeight+
this.c.childNodes[1].offsetHeight)+'px'
}
}
}
function acsinit(){
var acs=D.getElementsByClassName('accordion'),acsl=acs.length;
while(acsl--){
acs[acsl].addEventListener('click',acsf,false);
}
window.removeEventListener('load',acsinit,false);
}
window.addEventListener('load',acsinit,false);
})(document)
动画的css。
#container>div{
width:512px;height:48px;overflow:hidden;
-webkit-transition:all 300ms ease;
background-color:rgba(0,0,0,0.5);
}
#container>div>div:nth-child(1){
line-height:48px;text-align:center;
background-color:rgba(0,0,0,0.5);
}
html结构
<div id="container" class="accordion">
<div>
<div>Title</div>
<div>description</div>
</div>
<div>
<div>Title</div>
<div>description</div>
</div>
</div>
而且,如果您希望能够将它们全部关闭,则需要使用循环来检查它们是否被切换。
像这样的东西:
function openAll(){
var elements=container.childNodes,l=elements.length;
while(l--){
if(elements[l].classList.contains('hidden')){
elements[l].classList.remove('hidden');
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.