简体   繁体   中英

Toggling active class from li while removing active from any other li elements

Using an accordion for FAQs and having an issue getting the desired results. Trying to show/hide the .ac-content when clicking the .ac-header. Also want to toggle the active class of the .ac-header to have a background color change when .ac-header is active.

$(function() {
    $('.ac-header').click(function (e) {
    if ($(this).hasClass('active')) {            
        $(this).next('.ac-content').hide();
    } else {
        $('.ac-content').not(this).each(function () {
        $(this).hide();
    });
    $(this).next('.ac-content').show();            
    }
    $(this).toggleClass('active');
    });          
    $('#faqs-list li').click(function() {
    $('#faqs-list li.active').not(this).removeClass('active');
    $(this).toggleClass('active');
    });
});    


<ul id="faqs-list" class="fd-accordion">
 <li>
  <header class="ac-header">
   <h4>1. What are the benefits of purchasing a plan?</h4>
   <span class="arrow"></span>
  </header>
  <div class="ac-content">
   <p>Insert Answer</p>
  </div>
 </li>
 <li>
  <header class="ac-header">
   <h4>2. What is covered under the plan?</h4>
   <span class="arrow"></span>
  </header>
   <div class="ac-content">
    <p>Insert Answer</p>
   </div>
  </li>
</ul>

The following should work:

$(function() {
   $('#faqs-list li').on("click", function() {
       var isActive = $(this).is('.active');
       $('#faqs-list li.active').removeClass('active');
       $(this).toggleClass('active', !isActive);
   });  
});

So should this:

$(function() {
   $('#faqs-list li').on("click", function() {
       $('#faqs-list li.active').not(this).removeClass('active');
       $(this).toggleClass('active');
   });  
});

Pick the one you're most comfortable with. The problem lies in the fact that you call removeClass on the current element and it interferes with the toggleClass call.


Added after your edit:

Are you trying to achieve something like this?

 $(document).ready(function() { $(".ac-content").hide(); $('.ac-header').on("click", function (e) { $('.ac-header').not(this) .removeClass("active") .next(".ac-content") .hide(); $(this).toggleClass("active") .next(".ac-content") .toggle($(this).is(".active")); }); }); 
 header { cursor: pointer; } .active { color: red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul id="faqs-list" class="fd-accordion"> <li> <header class="ac-header"> <h4>1. What are the benefits of purchasing a plan?</h4> <span class="arrow"></span> </header> <div class="ac-content"> <p>Insert Answer</p> </div> </li> <li> <header class="ac-header"> <h4>2. What is covered under the plan?</h4> <span class="arrow"></span> </header> <div class="ac-content"> <p>Insert Answer</p> </div> </li> </ul> 

If I understand your question correctly, you can avoid using toggleClass altogether by simply using the following code.

$(function(){
     $('#faqs-list li').click(function() {
         //Removes the active class from any <li> elements

         if($(this).hasClass('active')){
             $(this).removeClass('active');
         } else {
             $(this).addClass('active');
         }
     });
});

There are so many dollar signs in your code that my head is spinning; how about yours?

Create an function which remembers the current highlighted elements, so it can undo it next time:

function make_swapper(classname) {
    var current;
    return function(elts) {
        (current || []).forEach(function(e) { e.classList.remove(classname); };
        (elts    || []).forEach(function(e) { e.classList.add   (classname); };
        current = elts;
    };
}

swap_active = make_swapper("active");

Now, to set the class on some elements and remove it from the old ones, just do

swap_active([elt1, elt2]);
swap_active([elt3, elt4]);

To achieve hide/show behavior, define the active class accordingly.

If you insist on doing this using jQuery, although I don't see the point, it would look something like this:

function make_swapper(classname) {
    var current = [];
    return function(elts) {
        current.removeClass(classname);
        elts.addClass(classname);
        current = elts;
    };
}
swap_active= make_swapper("active");

Now, to set the class on some elements and remove it from the old ones, just do

swap_active($('#foo .bar'));
swap_active($('#bar .foo'));  // class on previous elements automatically removed

Depending on the degree to which jQuery exposure has rotted your brain, you of course will want to make this into a jQuery plugin, so you can use the ultra-cool chaining syntax:

$('#foo .bar').swap_active()

In any case, the point of doing all this is to cleanly separate out, from everything else going on in your app, the basic notion that there is one set of elements that is currently assigned a given class, and then you can specify another set of elements, which are set to the given class after the class is removed from the previous elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM