DevKev
DevKev

Reputation: 6304

How can I use jQuery to toggle between 2 classes?

I am not sure toggleClass is the best way to do this, but I have a accordion menu and I am attempting to alternate the icon/image on the right side from a RIGHT arrow to a DOWN arrow.

The first click on the 3 menu items shows the DOWN image (.icon-03) but when I switch between the accordion items it does not go back to the RIGHT arrow image/class (.icon-04). thoughts?

/* Accordion */
$(document).ready(function () {
  $('#accordionFAQ > li > a').click(function(e){
    if ($(this).attr('class') != 'active'){
      $('#accordionFAQ li ul').slideUp();
      $(this).next().slideToggle();
      $('#accordionFAQ li a').removeClass('active');
      $(this).addClass('active');

      //add down arrow
      $('> span', this).toggleClass('icon-03 icon-04');

      //prevent page reload
      e.preventDefault();
    }
  });
});

Demo JS Fiddle: http://jsfiddle.net/957Fs/

Upvotes: 0

Views: 200

Answers (3)

Christoph
Christoph

Reputation: 51201

First of all, $(this).attr('class') != 'active' is very inefficient (and possibly fails to work altogether), use $(this).hasClass('active') instead.

After your comment, I re-added the classes - the following should work:

$('#accordionFAQ > li > a').click(function(e){
   if (! $(this).hasClass('active') ){
       $('.active')
           .find('span').toggleClass('icon-03 icon-04')
           .end().removeClass('active')
           .next().slideUp();
       $(this).find('span').toggleClass('icon-03 icon-04')
           .end().addClass('active')
           .next().slideDown();
       //prevent page reload
       e.preventDefault();
   }
});

Upvotes: 1

peterchon
peterchon

Reputation: 250

/* Accordion */
$(document).ready(function () {
  var accordionFAQ = $('#accordionFAQ');

  // let's use jQuery's .on() rather than .click()
  accordionFAQ.find('a').on({

    click:function(e){

      // prevent the default action
      e.preventDefault();

      // setup some variables
      var that = $(this);

      // close open ULs
      accordionFAQ.find('ul').slideUp();

      // remove .active from other controller
      accordionFAQ.find('.active').removeClass('active');

      // add .active to clicked controller and show UL
      that.addClass('active').next().slideDown();

      // remove .right from span
      accordionFAQ.find('.right').removeClass('right');

      // add .right to current controller's span
      that.find('span').addClass('right');

    }

  });

});

Then, you can have span's default image be the left arrow. and when you add a .right class, it will override the default image with a right arrow using CSS.

hope this helps.

Upvotes: 0

meavo
meavo

Reputation: 1042

When I look at the JSFiddle example it works for me, so I guess it's updated already. I'd like to make a suggestion though: it's perhaps a good idea to just toggle a class (e.g. 'is-active') on your list items and handle the rest with pure CSS. For example:

var $faq = $('#accordionFAQ');
$faq.on('click', '> li > a', function (event) {
    $(this).parent().toggleClass('is-active');
});

In your CSS you could do something like this:

#accordionFAQ > li > a span {
  // width, height etc
  background-position: x y;
}
#accordionFAQ > li.is-active > a span {
  background-position: x y;
 }

Just an idea; hope it's helpfull.

Upvotes: 0

Related Questions