2014-04-13 55 views
0

我想制作一个可展开的菜单,包含三个或更多项目。当其中一个项目被点击时,它会展开以显示<ul>,它下面是display: hidden
此外,我希望它的工作方式是,如果该菜单上的某个项目已经展开,如果我点击任何其他项目,它将在展开第二个项目之前收回第一个项目的内容(点击一个)。有没有更简单的方法来使这个可扩展的菜单?

我有的代码是this。我必须为我在那里的三个项目中的每一个定义不同的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; 
    }; 
}; 
+0

请问您可以发布相关代码 – caramba

+0

缩进无法正确显示在这里,但在JSFiddle他们很好。我似乎无法在这里正确格式化它。 – JNat

+0

你为什么不使用accordeon插件?为什么重新发明轮子?是否真的需要定制实现? – arieljuod

回答

1

我的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; 
} 

希望这有助于。

+0

这个完美的作品。但是它不会通过再次单击来折叠当前扩展的项目。 – JNat

+1

@JNat谢谢。我编辑我的答案上面和JSFiddle http://jsfiddle.net/naokiota/38W8X/12/ – naota

0

是还有一个更简单/(更好& &动画)的方式来写这样的事情。

  1. 它是动画
  2. 可以处理无穷的开关
  3. 不使用显示器没有
  4. 不使用循环
  5. 只有一个事件处理程序来控制所有的元素
  6. 你可以将任何类型的风格
  7. 您可以添加多个手风琴,只需添加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

http://jsfiddle.net/YjCbM/1/

这里是另一个版本

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); 

http://jsfiddle.net/Jj6FY/1/

读Verions(略有差异erent)

这基本上是一个手风琴插件

(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'); 
    } 
} 
} 
1

存储在一个变量当前扩大项目。

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; 
    } 
} 
3

如果我的第一个答案是复杂的,这里是一个CSS只有替代没有动画& js。

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

http://jsfiddle.net/vvLu2/

没有javascript ...

+0

不错,我不知道它可以完成只使用CSS。但是,如果我点击扩展项目,它不会折叠它。 – JNat

+0

这就是为什么我第一次发布我的复杂解决方案..该脚本可以提高一些简单actions.there无法通过单击折叠选定的项目的限制。 – cocco

相关问题