用原生 JS 做一個簡單的手風琴 Accordion / Collapse 功能

/

2021.07.23 補充:
留言區裡有人詢問能不能開了一個,就關閉前一個的功能,今日程式碼加上此功能。

2020.07.23 補充:
看到留言區裡有人問有沒有預設開啟的方法,程式碼做了點調整,只要在 .title-box 中加入 data-expanded="true",預設就會開啟囉~

從jQuery到原生JS

手風琴,英文單字是Accordion,但在很多套件上有時又稱Collapse。本篇筆記就用中文的手風琴比較好理解。

很久以前,有用jQuery寫了一個手風琴的功能,放在codePen上後看到有人點愛心跟Fork,覺得有趣:Collapse/Accordion plugin

今年開始在工作時逼自己寫原生的JS(Vanilla JavaScript),今天趁著意外的假日,試著把手風琴用原生JS寫了一個出來。寫完後發現,其實沒幾行就可以完成,也有了一點小小的成就感。

本篇就是開發過程的一個筆記,最後也會附上原始碼。這段先附上最後會完成的Demo:

https://letswritetw.github.io/augurio-collapse-accordion/


HTML

HTML的架構用最簡單的,最外面先包一層div,裡面每一組的項目用.callopse包。一個.collapse就是一組,一組裡有.title-box.contents-box,一個是頭,一個是會被隱藏的內容。


CSS

樣式的部份就簡單寫,因為之後要套到每個頁面時,每個頁面會有自己的設計。

針對手風琴打開、關閉時,寫了一個會變換「+」、「-」符號的轉變效果,主要是用2個span去刻成2條線,一條轉直的,當 .contents-box 被打開時再轉回横的。

以下範例code為了好閱讀,改用SASS:

這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝


JavaScript

JS的部份,寫了2個部份:

  1. 先抓每個 .contents-box 的高度,存在 data-height 裡,然後把高度設為0。
  2. 監聽每一個 .title-box 的點擊事件,如果 .title-box.active,那就把同一層的 .contents-box 高度寫回去。

之所以會有把高度寫回去的動作,而不是去改display none/block,是為了讓手風琴打開/關閉時會有jQuery slideUp、slideDown的效果。

而如果只是單純的寫height 0/100%,那即使寫了 transition: height,也一樣不會有slideUp、slideDown的樣子,一定要給指定的高度才行,所以才會有第一步的抓原始高度到 data-height 裡,讓 .title-box 被點擊時可以抓到原有的高度。


原始碼下載

本筆記原始碼的部份,Augustus整理放到Github上了。

https://github.com/letswritetw/augurio-collapse-accordion


Summary
用原生JS做一個簡單的手風琴Accordion/Collapse功能
Article Name
用原生JS做一個簡單的手風琴Accordion/Collapse功能
Description
本篇大綱:從jQuery到原生JS、HTML、CSS、JavaScript、原始碼下載。今年開始在工作時逼自己寫原生的JS(Vanilla JavaScript),今天趁著意外的假日,試著把手風琴用原生JS寫了一個出來。寫完後發現,其實沒幾行就可以完成,也有了一點小小的成就感。
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg

隨選筆記文

API

如何用 Mockoon 快速建立 Mock APIs Server

Vue

Vue Transitions 製作簡單的 Carousel / Slider / 輪播功能

WordPress

如何用 MAMP 在本機安裝 WordPress

WordPress

WordPress 基本介紹

Analytics Google

GA 報表:電子商務 內部宣傳 報表

Bot Telegram

Telegram Bot 學習筆記 – 5:取得使用者大頭照

Bot Telegram

Telegram Bot 學習筆記 – 3:鍵盤 Keyboard

API

如何用 Postman Mock Server 快速建立 API Server

API Front-End

用 Google Apps Script 寫一個 LINE 登入功能:上篇 – 前置作業

Vue

Vue.js 3 Composition API 基本學習筆記-2:fetch data、export / import

以下是留言,但關於留言的部份必需先讓你們知道:

本站的文章都是 Augustus 因為覺得有趣,才會實作並整理成筆記文而後進行發表。

如果留言是希望把 Demo 改成「你想要」的樣子,或是把功能改成「符合你需求」的樣子,

Sorry~ 除非那修改是 Augustus 也有興趣的,不然不會幫你們寫程式去面對工作或是交作業。

未來這類的留言不會再主動回覆。😎

另外,公開信箱是為了讓金流驗證用,

因為之前遇過幾次回信協助解決問題後,對方卻一聲謝謝也沒有,就這樣拿去幫工作交差。

因此決定不再回覆信件,有疑問就利用留言功能囉。

訂閱
通知
guest
10 Comments
最舊
最新
Inline Feedbacks
看所有留言
cath
cath
1 年 之前

想請問如果第一個collapse要預設每次點進來都是開的,點選title-box後才會收合,是有辦法做到的嗎?謝謝~

Ethan
Ethan
10 月 之前

請問一下,.title-box 被點擊時,加入 .active,這個部分有時候點到.tltle的文字與.icons的span會無法做動,請問有辦法解決嗎? 感謝!!

Ethan
Ethan
回覆給  Augustus
10 月 之前

謝謝你!!!! 你的分享對我很有幫助 ^_^

purge23
purge23
2 月 之前

您好,請問一下,如果滑鼠點選第一個選單時,選單內容打開了。
滑鼠再點選第二選單時,要如何讓第一個打開的選單內容”關閉”呢?
也就是一次,只要打開一個選單就好了!
能否指點一二呢!

purge23
purge23
回覆給  Augustus
2 月 之前

感激不盡!!!

purge23
purge23
回覆給  Augustus
2 月 之前

感謝啊~百忙之中的幫忙!
不過,我實在是新手,看了很久,不知從哪下手,能否指點一下,
若要有”子選單”的話,要怎麼處理啊!對我而言,真的是有點困難!
也就是說,像這樣子的選單:
第一冊—第一章—1-1 —1-2 —1-3
          —-第二章—1-1 —1-2 —1-3
第二冊—第一章—1-1 —1-2 —1-3
          —第二章—1-1 —1-2 —1-3
第三冊—第一章—1-1 —1-2 —1-3
          —第二章—1-1 —1-2 —1-3
像以上這樣的有子選單,要如何處理啊!
能否指點一二~!謝謝你!!

Pinkie
Pinkie
1 月 之前

請問若要將已點開的選單再按一次.title-box就收合,要新增哪個部份呢?