0

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);
}

  });
PhDeOliveira
  • 2,323
  • 4
  • 22
  • 25

1 Answers1

1

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);
Snowburnt
  • 6,523
  • 7
  • 30
  • 43
  • I triggering of the opening by adding an `.open` class already. I'm sort of already doing that.. just need to be able to close one thats currently open. - if that makes any sense – PhDeOliveira Oct 07 '13 at 20:23
  • Yeah, like I said, get the class with open and close it. To close it remove the open class and add the close class. To get it use getElementByClassName. to change and remove, see this post: http://stackoverflow.com/questions/195951/change-an-elements-css-class-with-javascript – Snowburnt Oct 07 '13 at 23:43
  • BTW, if I can offer some advice, it's MUCH easier with something like jQuery, I'll add the jquery code to my answer. – Snowburnt Oct 07 '13 at 23:44
  • If you are going to use jQuery you may aswell use jQueryUI and just run $( "#accordion" ).accordion(); – Michael Smith Oct 31 '13 at 09:16