Reputation: 101
const accordion = document.querySelector('.accordion');
const items = accordion.querySelectorAll('.accordion__item');
items.forEach((item) => {
const title = item.querySelector('.accordion__title');
title.addEventListener('click', (e) => {
const opened_item = accordion.querySelector('.is-open');
toggle_item(item);
if (opened_item && opened_item !== item) {
toggle_item(opened_item);
}
});
});
const toggle_item = (item) => {
const body = item.querySelector('.accordion__body');
const content = item.querySelector('.accordion__content');
if (item.classList.contains('is-open')) {
body.removeAttribute('style');
item.classList.remove('is-open');
}else {
body.style.height = body.scrollHeight + 'px';
item.classList.add('is-open');
}
}
.accordion__title {
background: gold;
}
.accordion__body {
border-radius: 5px;
height: 0;
overflow: hidden;
transition: height 0.3s ease-in-out;
}
<div class="accordion">
<div class="accordion__item">
<div class="accordion__title">Lorem ipsum dolor sit</div>
<div class="accordion__body">
<div class="accordion__content">
<ul>
<li>
x
</li>
</ul>
</div>
</div>
</div>
</div>
How can I edit this code to be opened by default without clicking on it when the page loaded? Code has 1 item now but I will add more items and I want to choose which item is open when the page loaded first.
I tried to do some changes but couldnt be successful with my poor javascript knowledge
Upvotes: 0
Views: 2005
Reputation: 32255
You just need to select the item through the NodeList generated and then assign the is-open
class to it through classList
. The last change should be in CSS to select the accordion__body
of the is-open
class. Please check the comments to see the changes.
const accordion = document.querySelector('.accordion');
const items = accordion.querySelectorAll('.accordion__item');
const openedItem = items[1]; // Change the value to select the item. This selects the 2nd element since it starts from 0.
items.forEach((item) => {
openedItem.classList.add("is-open"); // Add class to the open item.
const title = item.querySelector('.accordion__title');
title.addEventListener('click', (e) => {
const opened_item = accordion.querySelector('.is-open');
toggle_item(item);
if (opened_item && opened_item !== item) {
toggle_item(opened_item);
}
});
});
const toggle_item = (item) => {
const body = item.querySelector('.accordion__body');
const content = item.querySelector('.accordion__content');
if (item.classList.contains('is-open')) {
body.removeAttribute('style');
item.classList.remove('is-open');
} else {
body.style.height = body.scrollHeight + 'px';
item.classList.add('is-open');
}
}
.accordion__title {
background: gold;
}
.accordion__body {
border-radius: 5px;
height: 0;
overflow: hidden;
transition: height 0.3s ease-in-out;
}
.is-open .accordion__body { /* Display the opened item */
height: 100%;
}
<div class="accordion">
<div class="accordion__item">
<div class="accordion__title">Item 1</div>
<div class="accordion__body">
<div class="accordion__content">
<ul>
<li>
Hero can be anyone. Even a man knowing something as simple and reassuring as putting a coat around a young boy shoulders to let him know the world hadn't ended. Well, you see... I'm buying this hotel and setting some new rules about the pool area.
I'm Batman Someone like you. Someone who'll rattle the cages. No guns, no killing. The first time I stole so that I wouldn't starve, yes. I lost many assumptions about the simple nature of right and wrong. And when I traveled I learned the fear before a crime and the thrill of success. But I never became one of them.
Hero can be anyone. Even a man knowing something as simple and reassuring as putting a coat around a young boy shoulders to let him know the world hadn't ended. Someone like you. Someone who'll rattle the cages.
Does it come in black? Bats frighten me. It's time my enemies shared my dread. I will go back to Gotham and I will fight men Iike this but I will not become an executioner.
</li>
</ul>
</div>
</div>
</div>
<div class="accordion__item">
<div class="accordion__title">Item 2</div>
<div class="accordion__body">
<div class="accordion__content">
<ul>
<li>
Click on the first element, Robin!
</li>
</ul>
</div>
</div>
</div>
<div class="accordion__item">
<div class="accordion__title">Item 3</div>
<div class="accordion__body">
<div class="accordion__content">
<ul>
<li>
x3
</li>
</ul>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 61
You need to call toggle_item function when index is zero in foreach loop.
const accordion = document.querySelector('.accordion');
const items = accordion.querySelectorAll('.accordion__item');
const toggle_item = (item) => {
const body = item.querySelector('.accordion__body');
const content = item.querySelector('.accordion__content');
if (item.classList.contains('is-open')) {
body.removeAttribute('style');
item.classList.remove('is-open');
}else {
body.style.height = body.scrollHeight + 'px';
item.classList.add('is-open');
}
}
items.forEach((item, index) => {
const title = item.querySelector('.accordion__title');
if(index==0){
toggle_item(item);
}
title.addEventListener('click', (e) => {
const opened_item = accordion.querySelector('.is-open');
toggle_item(item);
if (opened_item && opened_item !== item) {
toggle_item(opened_item);
}
});
});
.container{
max-width: 800px;
margin: 0px auto;
}
.accordion__title {
background: gold;
}
.accordion__item{
position: relative;
border:1px solid #f0f0f0;
margin-top: 10px;
cursor:pointer;
}
.is-open .accordion__body{
margin:10px 0;
}
.accordion__title{
padding:5px 0;
}
.accordion__close{
position: absolute;
right:0px;
top:-10px;
}
.accordion__close li{
list-style: none
}
.accordion__body {
border-radius: 5px;
height: 0;
overflow: hidden;
transition: height 0.3s ease-in-out;
}
<div class="container">
<div class="accordion">
<div class="accordion__item">
<div class="accordion__title">Lorem ipsum dolor sit</div>
<div class="accordion__body">
<div class="accordion__content">
sdsdsdsdsd
</div>
</div>
<ul class="accordion__close">
<li>x</li>
</ul>
</div>
<div class="accordion__item">
<div class="accordion__title">Lorem ipsum dolor sit</div>
<div class="accordion__body">
<div class="accordion__content">
sdsdsdsdsd
</div>
</div>
<ul class="accordion__close">
<li>x</li>
</ul>
</div>
<div class="accordion__item">
<div class="accordion__title">Lorem ipsum dolor sit</div>
<div class="accordion__body">
<div class="accordion__content">
sdsdsdsdsd
</div>
</div>
<ul class="accordion__close">
<li>x</li>
</ul>
</div>
</div>
</div>
Upvotes: 0
Reputation: 42
You can just call the toggle_item function once at the initialization of the code, this way it will toggle from closed to opened:
const accordion = document.querySelector('.accordion');
const items = accordion.querySelectorAll('.accordion__item');
items.forEach((item) => {
const title = item.querySelector('.accordion__title');
title.addEventListener('click', (e) => {
const opened_item = accordion.querySelector('.is-open');
toggle_item(item);
if (opened_item && opened_item !== item) {
toggle_item(opened_item);
}
});
});
const toggle_item = (item) => {
const body = item.querySelector('.accordion__body');
const content = item.querySelector('.accordion__content');
if (item.classList.contains('is-open')) {
body.removeAttribute('style');
item.classList.remove('is-open');
}else {
body.style.height = body.scrollHeight + 'px';
item.classList.add('is-open');
}
}
toggle_item(items[0]);
.accordion__title {
background: gold;
}
.accordion__body {
border-radius: 5px;
height: 0;
overflow: hidden;
transition: height 0.3s ease-in-out;
}
<div class="accordion">
<div class="accordion__item">
<div class="accordion__title">Lorem ipsum dolor sit</div>
<div class="accordion__body">
<div class="accordion__content">
<ul>
<li>
x
</li>
</ul>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 716
Just add is-open
class to the item you want it to be opened by default
<div class="accordion__item is-open">
and add this inital style for is-open
class
.is-open .accordion__body {
height: 50px; // Or whatever inital value you want
}
Upvotes: 1