- 1種icon CodePen
- 2種icon切換 CodePen
- plus icon 套件 fontawesome v4.7
- minus icon 套件 fontawesome v4.7
1種icon | Youtube | FAQ accordion using HTML, CSS, JavaScript
2種icon切換
問題:transition: max-height 1.4s ease;
和animation: fade 1s ease;
解釋在此應用上的效果?
- .answer的初始狀態設置為
max-height: 0; overflow: hidden;
,當元素被隱藏時,其高度為0並且超出部分被隱藏。 - 當
.faq.active .answer
被標記為.active時,其max-height屬性變為300px,使得.answer元素展開到300px的高度。同時,overflow: hidden;的設置確保了多餘的部分仍然被隱藏。
transition: max-height 1.4s ease;
指定從一個max-height值到另一個max-height值的轉場效果,以便在展開或收縮時產生動畫效果。
animation: fade 1s ease;
- 是為了
.faq.active .answer
元素添加一個名為fade的動畫效果。 - 這個動畫效果是在展開時播放的,持續1秒,使用ease作為時間函數。
- fade動畫會從(from)元素透明度為0和Y軸向上偏移10px開始,然後(to)漸變到完全不透明(透明度為1)和Y軸偏移為0px。
- 在展開時的淡入和從上向下移動的動畫效果。
問題:const icon = faq.querySelector('.icon')
為什麼不是const icon = document.querySelector('.icon')
?
使用faq.querySelector('.icon')
的理由:
作用範圍限制:
faq.querySelector('.icon')
表示僅在每個.faq
元素的範圍內尋找 .icon 元素。
這是因為 faq 是我們在 forEach 迴圈中正在遍歷的每個常見問題項目,它代表了單個項目。避免全域搜索:
如果使用document.querySelector('.icon')
,則會從整個文檔中查找第一個符合條件的 .icon 元素。這樣做在某些情況下可能可行,但如果有多個常見問題項目,並且每個項目都有自己的 .icon 元素,那麼document.querySelector('.icon')
只會返回第一個找到的元素,無法精確地對應到每個項目的相應圖示。適用於動態操作:
使用faq.querySelector('.icon')
讓我們能夠在每次點擊常見問題項目時,確保只修改該項目內部的圖示元素,而不會影響其他項目的圖示。這是因為每個 faq 都有自己的內部作用範圍,使得更改只影響單個項目,而不會影響其他項目。
總之,faq.querySelector('.icon')
更加具體和精確選擇了我們想要操作的每個常見問題項目內部的圖示元素,而不是全域性地查找整個文檔中的 .icon 元素。這樣做有助於保持代碼的清晰度和功能的可預測性,特別是在處理多個類似元素時。
const faqs = document.querySelectorAll('.faq')
faq 是NodeList物件也就是節點的集合。
雖然 NodeList 不是 Array ,但仍可以使用 forEach() 方法來進行迭代。
MDN | NodeList
MDN | NodeList.prototype.forEach()
chatGPT
其他迭代 NodeList 的方法:
for...of 迴圈:
使用 for...of 迴圈可以方便地遍歷 NodeList。
這種方法適用於 NodeList、Array、TypedArray、Map 和 Set 等具有迭代器的對象。
const faqs = document.querySelectorAll('.faq');
for (const faq of faqs) {
// 在這裡對每個 .faq 元素進行操作
}
forEach 方法(僅限於 Array):
NodeList 是 DOM 中的一種特殊集合,並不是嚴格意義上的陣列,因此並不直接支持 forEach 方法。
但可以使用 Array.from 或者 Array.prototype.forEach.call 將 NodeList 轉換為陣列,然後使用 forEach 方法。
const faqs = document.querySelectorAll('.faq');
Array.from(faqs).forEach(faq => {
// 在這裡對每個 .faq 元素進行操作
});
// 或者使用 call 方法
Array.prototype.forEach.call(faqs, faq => {
// 在這裡對每個 .faq 元素進行操作
});
forEach 方法的注意事項:
在使用 forEach 方法時,確保 NodeList 已經被轉換為陣列,或者直接使用 for...of 迴圈來遍歷 NodeList。
總結來說,NodeList 與陣列有些相似,但它們不是同一類型。對於 NodeList,你可以使用 for...of 迴圈來遍歷,或者將其轉換為陣列後再使用 forEach 方法進行操作。