简体   繁体   中英

jQuery Toggle only one div with the same class on click and toggle class

I am trying to toggle the only div respected to the menu icon and want to keep rest of divs hidden. If any of them is opened than hide them all but the clicked one.

Also, want to toggle rotate class on the menu icon so when the respective div is opened it shows rotated and when hidden that it will have a normal state.

I am having trouble achieving the result with below code. Can someone help me to fix this?

Code:

 $('.more-buttons').each(function() { $(this).on('click', function() { if ($(this).hasClass('rotate')) { $(this).removeClass('rotate'); } var id = $(this).attr('id'); $('#' + id).toggleClass('rotate'); $('#' + id).next('.additional-buttons-model').slideToggle('fast'); }); }); 
 <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="more-buttons" id="551"> <i class="material-icons">more_horiz</i> </div> <div class="additional-buttons-model" data-id="551"> <div class="view-buttons"> <input class="light-button" name="doedit" type="submit" value="edit"> <input class="light-button" name="doclose" type="submit" value="close"> <input class="light-button" name="dohide" type="submit" value="hide"> </div> </div> 

Before showing the content of the clicked button you have to hide the other content. I have done that. Check out the code below:

 $('.more-buttons').each(function () { $(this).on('click', function () { var clickbtn = $(this); $('.more-buttons').not(clickbtn).each(function(){ $(this).removeClass('rotate'); }); var id = clickbtn.attr('id'); $('#' + id).toggleClass('rotate'); var content = $('#' + id).next('.additional-buttons-model'); $('.additional-buttons-model').not(content).each(function(){ $(this).css('display','none'); }); content.slideToggle('fast'); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div class="more-buttons" id="551"> <i class="material-icons">more_horiz</i> </div> <div class="additional-buttons-model" data-id="551"> <div class="view-buttons"> <input class="light-button" name="doedit" type="submit" value="edit"> <input class="light-button" name="doclose" type="submit" value="close"> <input class="light-button" name="dohide" type="submit" value="hide"> </div> </div> <div class="more-buttons" id="552"> <i class="material-icons">more_horiz</i> </div> <div class="additional-buttons-model" data-id="552"> <div class="view-buttons"> <input class="light-button" name="doedit" type="submit" value="edit"> <input class="light-button" name="doclose" type="submit" value="close"> <input class="light-button" name="dohide" type="submit" value="hide"> </div> </div> <div class="more-buttons" id="553"> <i class="material-icons">more_horiz</i> </div> <div class="additional-buttons-model" data-id="553"> <div class="view-buttons"> <input class="light-button" name="doedit" type="submit" value="edit"> <input class="light-button" name="doclose" type="submit" value="close"> <input class="light-button" name="dohide" type="submit" value="hide"> </div> </div> <div class="more-buttons" id="554"> <i class="material-icons">more_horiz</i> </div> <div class="additional-buttons-model" data-id="554"> <div class="view-buttons"> <input class="light-button" name="doedit" type="submit" value="edit"> <input class="light-button" name="doclose" type="submit" value="close"> <input class="light-button" name="dohide" type="submit" value="hide"> </div> </div> 

As per the comment I am adding the following code:

$('body').not('.more-buttons').click(function () {
    var clickbtn = $('.more-buttons');
    $(clickbtn).each(function(){
        $(this).removeClass('rotate');
    });
});

$('body').not('.additional-buttons-model').click(function () {
    var content = $('.additional-buttons-model');
    $(content).each(function(){
       $(this).css('display','none');
    });
});

Add the above code in your script.

In order to achieve the desired effect you can use the following code:

/* Cache the buttons. */
var btns = $('.more-buttons');

/* When a button is clicked... */
btns.on('click', function(e) {
   var
      /* Cache the clicked button. */
      btn = $(this),

      /* Cache the corresponding div. */
      div = btn.next('.additional-buttons-model');

   /* Toggle the 'rotate' class. */
   btn.toggleClass('rotate');

   /* Remove the rotate class from every button except the one clicked. */
   btns.not(btn).removeClass('rotate');

   /* Slide Up all divs but the one following the button. */
   btn.siblings('.additional-buttons-model').not(div).slideUp('fast');

   /* Slide the div following the button. */
   div.slideToggle('fast');

   /* Prevent the propagation of the event to the body. */
   e.stopPropagation();
});

/* When the user clicks on the body of the document... */
$("body").on("click", function () {
   /* Cache the buttons. */
   var btns = $(".more-buttons");

   /* Remove the 'rotate' class from all buttons. */
   btns.removeClass("rotate");

   /* Hide all divs of additional buttons. */
   btns.siblings('.additional-buttons-model').slideUp('fast');
});

In simple terms, the above code does three things regarding the div elements:

  1. First, it slides all div elements not following the clicked button up.
  2. Then, it slides the div corresponding to the clicked button up or down.
  3. When the body is clicked, all div elements are slid up and all icons lose the 'rotate' class.

Notes: (about your code 😊 )

  1. Instead of using each you can simply say $('.more-buttons').on('click', ...) to take advantage of the loop jQuery does internally.
  2. Instead of using $(this) over and over, just cache it once and use the variable. This way, only a single jQuery object will be created each time instead of 4.
  3. There is no reason to cache and use the id of the clicked button (at least in the code you provided in the question) .

Snippet:

 /* Cache the buttons. */ var btns = $('.more-buttons'); /* When a button is clicked... */ btns.on('click', function(e) { var /* Cache the clicked button. */ btn = $(this), /* Cache the corresponding div. */ div = btn.next('.additional-buttons-model'); /* Toggle the 'rotate' class. */ btn.toggleClass('rotate'); /* Remove the rotate class from every button except the one clicked. */ btns.not(btn).removeClass('rotate'); /* Slide Up all divs but the one following the button. */ btn.siblings('.additional-buttons-model').not(div).slideUp('fast'); /* Slide the div following the button. */ div.slideToggle('fast'); /* Prevent the propagation of the event to the body. */ e.stopPropagation(); }); /* When the user clicks on the body of the document... */ $("body").on("click", function () { /* Cache the buttons. */ var btns = $(".more-buttons"); /* Remove the 'rotate' class from all buttons. */ btns.removeClass("rotate"); /* Hide all divs of additional buttons. */ btns.siblings('.additional-buttons-model').slideUp('fast'); }); 
 /* Used to allow you to test the click on the body in the snippet. */ html, body { height: 100%; } 
 <!-- jQuery Script --> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="more-buttons" id="551"> <i class="material-icons">more_horiz</i> </div> <div class="additional-buttons-model" data-id="551"> <div class="view-buttons"> <input class="light-button" name="doedit" type="submit" value="edit"> <input class="light-button" name="doclose" type="submit" value="close"> <input class="light-button" name="dohide" type="submit" value="hide"> </div> </div> <div class="more-buttons" id="552"> <i class="material-icons">more_horiz</i> </div> <div class="additional-buttons-model" data-id="552"> <div class="view-buttons"> <input class="light-button" name="doedit" type="submit" value="edit"> <input class="light-button" name="doclose" type="submit" value="close"> <input class="light-button" name="dohide" type="submit" value="hide"> </div> </div> <div class="more-buttons" id="553"> <i class="material-icons">more_horiz</i> </div> <div class="additional-buttons-model" data-id="553"> <div class="view-buttons"> <input class="light-button" name="doedit" type="submit" value="edit"> <input class="light-button" name="doclose" type="submit" value="close"> <input class="light-button" name="dohide" type="submit" value="hide"> </div> </div> 

Please see the jsfiddle demo.

$('.more-buttons').on('click', function () {
  if($(this).hasClass('rotate')) {
    return false;
  }

  $(this).parent().find('.additional-buttons-model').slideUp('fast');
  $(this).parent().find('.more-buttons').removeClass('rotate');

  $(this).addClass('rotate');
  $(this).next('.additional-buttons-model').slideDown('fast');
});

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