2017-03-12 225 views
1

如果其中一個面板已打開,我們希望這樣做會在您點擊另一個面板時關閉。 我看了一些類似於我的其他問題,但似乎他們都使用不同的面板方法。打開另一個面板時關閉另一個面板

繼承人它的一個小提琴:https://jsfiddle.net/3q87y2u8/

繼承人的JS:

var acc = document.getElementsByClassName("accordion"); 
    var i; 

     for (i = 0; i < acc.length; i++) { 
      acc[i].onclick = function() { 
      this.classList.toggle("active"); 
      var panel = this.nextElementSibling; 
      if (panel.style.maxHeight){ 
      panel.style.maxHeight = null; 
    } else { 
    panel.style.maxHeight = panel.scrollHeight + "px"; 
    } 
    } 
} 

我也喜歡當上空盤旋,以獲得 '+' 來改變顏色。有點像目前的文字。雖然我似乎無法在CSS中調用它。

謝謝!

+0

你爲什麼不使用JS庫如jQuery? –

回答

0

縮小按鈕點擊後的所有div。這裏https://jsfiddle.net/3q87y2u8/3/

var acc = document.getElementsByClassName("accordion"); 
      var i; 

       for (i = 0; i < acc.length; i++) { 
        acc[i].onclick = function() { 
        this.classList.toggle("active"); 
    var panels=document.getElementsByClassName("panel"); 
    for (j = 0; j < panels.length; j++) { 
    panels[j].style.maxHeight = null; 
    } 
        var panel = this.nextElementSibling; 
        if (panel.style.maxHeight){ 
        panel.style.maxHeight = null; 
      } else { 
      panel.style.maxHeight = panel.scrollHeight + "px"; 
      } 
      } 
     } 
+0

似乎工作,但那裏有背景顏色有點bug了,不要回到它應該如何。看到這裏:https://jsfiddle.net/cc1hj0kn/ –

+0

它也不會讓你關閉你剛剛打開的面板 –

0

的的jsfiddle審查你的代碼後,我發現,你只打開當前標籤和不關閉其他標籤。所以試試這個

var acc = document.getElementsByClassName("accordion"); 
var i; 

for (i = 0; i < acc.length; i++) { 
    acc[i].onclick = function() { 
     this.classList.toggle("active"); 
     var panel = this.nextElementSibling; 
     var panels=document.getElementsByClassName("panel"); 
     for (j = 0; j < panels.length; j++) { 
      panels[j].style.maxHeight = null; 
     } 
     if (panel.style.maxHeight){ 
      panel.style.maxHeight = null; 
     } else { 
      panel.style.maxHeight = panel.scrollHeight + "px"; 
     } 
    } 
} 
+0

它似乎工作,但仍然像其他人一樣大。當你點擊anotehr one時你會關閉,但你不能關閉剛打開的那個。如果關閉的話,背景顏色也不會恢復正常 –

+0

@WarrenBreedlove它已關閉,您只需要更改其類別 –

0

一個更可讀和更有效的方法是簡單地持有對以前切換的手風琴項目的引用。

當onclick被調用時,您首先需要檢查cur是否是點擊面板。這樣,切換cur就會關閉它。接下來,將cur設置爲null,所以當你點擊不同的面板時它不會打開前面的面板。然後確保退出該功能。請注意,您必須在非檢查cur之前執行此操作。

否則,請檢查當前活動的項目以確保它不爲空,然後切換cur和this。通過設置cur到這個來包裝它,所以下一次它可以再次完成!

而且,這裏有一個小提琴:https://jsfiddle.net/d7smh9ru/4/

var cur = null; 
var acc = document.getElementsByClassName("accordion"); 
var i; 

for (i = 0; i < acc.length; i++) { 
    acc[i].onclick = function() { 

    // Only close already open panel 
    if (cur == this) { 
     toggleItem(cur); 
     cur = null; 
     return; 
    } 

    // Close current panel, and open this panel 
    if (cur) { 
     toggleItem(cur); 
    } 

    toggleItem(this); 
    cur = this; 
    } 
} 

function toggleItem(item) { 
    item.classList.toggle("active"); 
    var panel = item.nextElementSibling; 
    if (panel.style.maxHeight) { 
    panel.style.maxHeight = null; 
    } else { 
    panel.style.maxHeight = panel.scrollHeight + "px"; 
    } 
} 
+0

這與其他人說的話結合起來似乎讓我知道我要在哪裏感謝所有人!我在這裏與你的js有一個問題。它似乎工作超級光滑,乾淨,正是我想要的!但是現在如果你打開一個你不能關閉它。如果你打開另一個關閉哪個有人打開,但你不能點擊一個打開的關閉它。它的一個小東西,但沒有多少點在' - '的跡象顯示人們可以關閉xD這是我現在得到的,如果你有任何建議:https://jsfiddle.net/d7smh9ru/ –

+0

哦,哎呀!我會用我的建議編輯答案。 – hola

+0

似乎工作!謝謝。而我德夫現在瞭解一點吧 –

1

你可以得到當前活動的元素,然後取出,像這樣的活動類:

// Is an array of elements matching the selector 
var active = document.getElementsByClassName('active'); 

// If there are any matching elements and it is not the same one that has just been clicked on 
if (active.length && active[0] !== this) { 
    active[0].classList.remove('active'); 
} 

一邊評論(你是當然可以忽略!):對於最大高度,你不需要計算出高度(除非它干擾了你已經設置了頁面結構的方式)。你可以使用一些很大的高度,因爲它是你設置的最大高度,而不是高度,它會自動進入它的自然高度。您還可以使用CSS(包括動畫)來實現此目的,並且還會在下面添加更新加號上的懸停文字。

// Set regular state height to 0 and add a transition effect 
.panel { 
    max-height: 0px; 
    transition: max-height .25s ease; 
} 

// For whatever button is active find the adjacent panel and set its max height and a transition effect 
.active + .panel { 
    max-height: 250px; 
    transition: max-height .25s ease; 
} 

// Here is where you change the color of the active and hovered plus/minus sign 
button.accordion.active:after, 
button.accordion:hover:after { 
    color: red; 
} 

https://jsfiddle.net/xz2mpzg2/1/ https://jsfiddle.net/xz2mpzg2/2/

+0

啊謝謝你這個工作!和ty的評論。隨着你現在在你的小提琴中。當你打開另一個以前打開過的div時,只會坐在那裏等待另一個div,然後關閉後再關閉。它有點看起來越野車。我搞砸了轉型的時機,但似乎沒有解決它。有任何想法嗎?除此之外,它的完美! @Pango –

+0

嗯,我不能得到那麼多的延遲,但嘗試設置最大高度:1px而不是0.我不是100%確定這一點,讓我知道如果這樣做有什麼,如果不是我可以再看一眼。 – Pango

+0

它似乎沒有解決它。它可能看起來更好,但它的基本相同,我認爲 –

0

我相信你正在尋找的東西是這樣的:JSFiddle

我會經歷每一次我做的改變,並且每個陳述也被評論,但作爲一般校長,我改變了你的代碼,使用圍繞每組按鈕/文本的包裝div,並且我把文本放在裏面一個內在的div所以它會尊重max-height。而不是事件處理程序修改其下一個兄弟,這會失敗,例如,如果您的段落單獨包含在p標記中,而不是使用p中的br標記斷行。這也使得使用父類的:hover僞類實現懸停改變加顏色效果變得微不足道。

所以,如果你改變你的按鈕/文本組:

<button class="accordion">Home</button> 
<div class="panel"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis    nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> 
</div> 

到:

<div class="panel"> 
    <button class="accordion">Home</button> 
    <div class="content"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis   nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> 
    </div> 
</div> 

,並更新你的CSS,改變你的panelcontent(以前開始上線50你的JSFiddle):

.content { 
    overflow: hidden; 
    transition: max-height 0.2s ease-out; 
    padding-left: 50px; 
    background-color: #f6f6f6; 
    width: 220px; 
    font-size: 10px; 
    max-height: 100px; 
} 

並使用CSS設置最大高度爲0,非開板

div.panel:not(.opened) > .content { 
    max-height: 0; 
} 

然後,您可以設置按鍵的事件偵聽器,並簡單地切換父opened類:

document.querySelectorAll('.accordion') 
    .forEach(element => { 
    element.onclick = function() { 

     // first, iterate over other open panels and close them... 
     // note: using Array.from(...) so we can filter the result below. 
     Array.from(document.querySelectorAll('.panel.opened')) 

     // ...but skip the clicked panel, which will be dealt with below 
     // [edit] we filter here so we can close an already-open panel 
     .filter(panel => panel !== this.parentNode) 

     .forEach(panel => { 

      // toggle the 'opened' class, forcing `false` 
      panel.classList.toggle('opened', false) 

      // and remove styling that was set on the element itself 
      panel.querySelector('.content').style.maxHeight = null; 
     }); 

     // now toggle the clicked panel's 'opened' class and capture its new value 
     const toggled = this.parentNode.classList.toggle('opened'); 

     // reference the new div.content, inside the button's parent 
     const content = this.parentNode.querySelector('.content'); 

     // and either fix its max height or unset it, depending on new state 
     content.style.maxHeight = toggled? `${content.scrollHeight}px` : null; 
    } 
    }); 

最後,如果你想改變上突出「+」色,現在你可以做到這一點使用上的.panel僞類:hover

div.panel:hover > button.accordion:after { 
    color: red; 
}