Reputation: 2333
I've been trying to get an accordion movement going with javascript.
The problem that I'm having is having one close if it's already open and stay closed.
Right now the according closing one and opening another when I click a different div.
I see that the argument is always resolving to true because I'm removing the classes.. but I can't seem to find a away to get around that so I could have a nice accordion.
<div class="speaker-container">
<div class="span3 offset1 speaker" id="sp-info-0">
<div class="speaker-img">
<div class="hover"></div>
<img src="" alt="">
</div>
<h4>Title</h4>
</div>
<div class="speaker-info" id="sp-info-0">
<button class="close-speaker">Close</button>
<h2>Title</h2>
</div>
<div class="span3 offset1 speaker" id="sp-info-1">
<div class="speaker-img">
<div class="hover"></div>
<img src="" alt="">
</div>
<h4>Sub Title</h4>
</div>
<div class="speaker-info" id="sp-info-1">
<button class="close-speaker">Close</button>
<h2>Title</h2>
</div>
<div class="span3 offset1 speaker" id="sp-info-2">
<div class="speaker-img">
<div class="hover"></div>
<img src="" alt="">
</div>
<h4>Title</h4>
</div>
<div class="speaker-info" id="sp-info-2">
<button class="close-speaker">Close</button>
<h2>Title</h2>
</div>
</div>
var timer;
$('.speaker-container .speaker').on('click', function(){
var speakerContainer = document.getElementsByClassName('speaker-container');
var self = this;
var children = $('.speaker-container').children();
var selfHeight = this.clientHeight;
var parentOffset = this.parentElement.offsetHeight;
var selfOffset = this.nextElementSibling.offsetHeight;
console.dir(children);
console.log(parentOffset);
$('.speaker-container').removeClass('open').css({'height' : selfHeight + 'px'});
for (var i = 0; i < children.length; i++) {
if (children[i].className == 'speaker-info fade') {
console.dir(children[i]);
$(children[i]).removeClass('fade');
}
}
if (self.parentElement.className !== 'speaker-container open' && self.nextElementSibling.className !== 'speaker-info fade') {
timer = setTimeout(function(){
self.parentElement.setAttribute('class' , 'speaker-container open');
self.parentElement.style.height = selfOffset + selfHeight + 'px';
self.nextElementSibling.style.top = selfHeight + 'px';
self.nextElementSibling.setAttribute('class' , 'speaker-info fade');
// return false;
}, 500);
} else {
$('.speaker-container').removeClass('open').css({'height' : selfHeight + 'px'});
self.nextElementSibling.setAttribute('class' , 'speaker-info');
window.clearTimeout(timer);
}
});
Upvotes: 0
Views: 1854
Reputation: 6922
Make a class that has the item open. (let's say the class is "open")
Make a class that has the item closed. (let's say the class is closed")
let's say all the accordion items are in the accordion class.
function that opens an item:
cycle through and remove any existing open item classes, add closed class.
add open class to the selected item.
by default, give closed class to all items (except the one you want open by default, if any)
with javascript it would look something like:
function openOnClick()
{
var openaccordion=document.getElementsByClassName('open');
openaccordion.className.replace( /(?:^|\s)open(?!\S)/g , 'close' );
this.className.replace( /(?:^|\s)close(?!\S)/g , 'open' );
}
with jQuery it would look like this:
$('div.accordion').click(function(){
$('.open').removeClass('open').addClass('close');
$(this).removeClass('close').addClass('open');
}
you can use jqueryui to get some sliding effects in there pretty simply too:
$(this).switchClass('close','open',1000);
Upvotes: 1