我在我的頁面上實現了一個accordion系統,其功能類似于其他accordion組件。單擊折疊項時,它會打開,單擊另一項時,前一項會關閉。我的accordion組件的獨特之處在于,當一個項目被打開時,它總是保持在粘性頂部標題的下方。目前,該功能工作正常,但我想添加動畫打開和關閉的手風琴項目。此外,我有錨標記,當點擊時,滾動到相應的折疊項并打開它。我試著使用accContent.style.maxHeight,但是這就產生了保持折疊項和動畫的正確位置的問題。
我將非常感謝您的幫助,解決這些問題,并實現動畫的手風琴項目,同時確保他們始終保持在粘性標題下的預期效果。
謝謝你。
// Get the height of the sticky nav bar
const stickyNavHeight = 80; // Height of the sticky navigation
// Get all accordion elements
const accordions = document.querySelectorAll('.accordion');
// Loop through each accordion
accordions.forEach(accordion => {
const accordionItems = accordion.querySelectorAll('.accordion__item');
// Add click event listener to each accordion item
accordionItems.forEach(item => {
const button = item.querySelector('.accordion__button');
const content = item.querySelector('.accordion__content');
button.addEventListener('click', () => {
// Check if the clicked item is already open
const isOpen = button.classList.contains('accordion__button--is-open');
// Close all accordion items within the current accordion
accordionItems.forEach(accItem => {
const accButton = accItem.querySelector('.accordion__button');
const accContent = accItem.querySelector('.accordion__content');
accButton.classList.remove('accordion__button--is-open');
accContent.style.display = 'none';
});
// Open the clicked item if it was closed
if (!isOpen) {
button.classList.add('accordion__button--is-open');
content.style.display = 'block';
// Calculate position of the accordion item
const rect = item.getBoundingClientRect();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const position = rect.top + scrollTop;
// Scroll below the sticky nav bar
window.scrollTo({
top: position - stickyNavHeight,
behavior: 'smooth'
});
}
});
});
});
// Get all anchor tags with the class 'js-accordion-open'
const anchorLinks = document.querySelectorAll('.js-accordion-open');
// Add click event listener to each anchor tag
anchorLinks.forEach(link => {
link.addEventListener('click', event => {
event.preventDefault(); // Prevent the default anchor tag behavior
const targetId = link.getAttribute('href'); // Get the target accordion item ID
// Find the corresponding accordion item based on the target ID
const targetAccordionItem = document.querySelector(targetId);
if (targetAccordionItem) {
const accordion = targetAccordionItem.closest('.accordion');
const accordionItems = accordion.querySelectorAll('.accordion__item');
// Close all accordion items within the current accordion
accordionItems.forEach(accItem => {
const accButton = accItem.querySelector('.accordion__button');
const accContent = accItem.querySelector('.accordion__content');
if (accItem === targetAccordionItem) {
// Open the target accordion item
accButton.classList.add('accordion__button--is-open');
accContent.style.display = 'block';
} else {
// Close other accordion items
accButton.classList.remove('accordion__button--is-open');
accContent.style.display = 'none';
}
});
// Calculate position of the target accordion item
const rect = targetAccordionItem.getBoundingClientRect();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const position = rect.top + scrollTop;
// Scroll below the sticky nav bar
window.scrollTo({
top: position - stickyNavHeight,
behavior: 'smooth'
});
}
});
});
// Find the default accordion item and open it
const defaultButtons = document.querySelectorAll('.accordion__button--is-open');
defaultButtons.forEach(defaultButton => {
const defaultItem = defaultButton.closest('.accordion__item');
const defaultContent = defaultItem.querySelector('.accordion__content');
defaultContent.style.display = 'block';
});
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 80px;
background: darkblue;
z-index: 1;
}
.card {
margin-top: 100px;
}
.accordion {
width: 650px;
margin-bottom: 224px;
border-top: solid 4px #000;
background-color: #fff;
}
.accordion__item {
border-bottom: 1px solid #000;
}
.accordion__button {
display: flex;
position: relative;
align-items: center;
text-align: left;
padding: 20px 0 20px 16px;
margin: 0;
width: 100%;
max-width: none;
height: auto;
border: none;
outline: none;
border-radius: 0;
transition: .4s;
background: none;
}
.accordion__title {
flex: 1;
font-size: 16px;
line-height: 1.5;
}
.accordion__icon {
position: relative;
flex: none;
transform: rotate(0);
width: 48px;
height: 24px;
transition: transform 380ms;
}
.accordion__icon::before, .accordion__icon::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #222;
width: 18px;
height: 4px;
}
.accordion__icon::after {
transform: rotate(90deg) translate(-50%, -50%);
transform-origin: top left;
}
.accordion__body {
background-color: #fff;
overflow: hidden;
transition: max-height 1.2s ease-out;
}
.accordion__content {
display: none;
margin: 16px;
}
.accordion__button--is-open {
border-bottom: none;
background: grey !important;
}
.accordion__button--is-open .accordion__icon {
transform: rotate(135deg);
transition: transform 380ms;
}
<header>
<nav></nav>
</header>
<div class="card">
<ul class="list">
<li class="list__item">
<a href="#acc1" class="js-accordion-open">Accordion item 1</a>
</li>
<li class="list__item">
<a href="#acc2" class="js-accordion-open">Accordion item 2</a>
</li>
<li class="list__item">
<a href="#acc3" class="js-accordion-open">Accordion item 3</a>
</li>
<li class="list__item">
<a href="#acc4" class="js-accordion-open">Accordion item 4</a>
</li>
</ul>
</div>
<div class="accordion">
<div class="accordion__item" id="acc1">
<button class="accordion__button accordion__button--is-open">
<span class="accordion__title">Accordion item 1</span>
<span class="accordion__icon"></span>
</button>
<div class="accordion__body">
<div class="accordion__content">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore magni, nostrum debitis deserunt minima laborum molestiae? Fuga omnis excepturi dolor a veniam rerum. Corporis tempora a debitis provident. Quia, sed.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore magni, nostrum debitis deserunt minima laborum molestiae? Fuga omnis excepturi dolor a veniam rerum. Corporis tempora a debitis provident. Quia, sed.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore magni, nostrum debitis deserunt minima laborum molestiae? Fuga omnis excepturi dolor a veniam rerum. Corporis tempora a debitis provident. Quia, sed.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore magni, nostrum debitis deserunt minima laborum molestiae? Fuga omnis excepturi dolor a veniam rerum. Corporis tempora a debitis provident. Quia, sed.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore magni, nostrum debitis deserunt minima laborum molestiae? Fuga omnis excepturi dolor a veniam rerum. Corporis tempora a debitis provident. Quia, sed.</p>
</div>
</div>
</div>
<div class="accordion__item" id="acc2">
<button class="accordion__button">
<span class="accordion__title">Accordion item 2</span>
<span class="accordion__icon"></span>
</button>
<div class="accordion__body">
<div class="accordion__content">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore magni, nostrum debitis deserunt minima laborum molestiae? Fuga omnis excepturi dolor a veniam rerum. Corporis tempora a debitis provident. Quia, sed.</p>
</div>
</div>
</div>
<div class="accordion__item" id="acc3">
<button class="accordion__button">
<span class="accordion__title">Accordion item 3</span>
<span class="accordion__icon"></span>
</button>
<div class="accordion__body">
<div class="accordion__content">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore magni, nostrum debitis deserunt minima laborum molestiae? Fuga omnis excepturi dolor a veniam rerum. Corporis tempora a debitis provident. Quia, sed.</p>
</div>
</div>
</div>
<div class="accordion__item" id="acc4">
<button class="accordion__button">
<span class="accordion__title">Accordion item 4</span>
<span class="accordion__icon"></span>
</button>
<div class="accordion__body">
<div class="accordion__content">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore magni, nostrum debitis deserunt minima laborum molestiae? Fuga omnis excepturi dolor a veniam rerum. Corporis tempora a debitis provident. Quia, sed.</p>
</div>
</div>
</div>
</div>