2014-04-13 84 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

相關問題