簡體   English   中英

有沒有更簡單的方法來制作此可擴展菜單?

[英]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

http://jsfiddle.net/vvLu2/

沒有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;
}

希望這可以幫助。

是的,有一種更簡單/(更生動有趣的動畫)的方式來編寫類似的東西。

  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/

可讀版本(略有不同)

這基本上是一個手風琴插件

(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM