Jquery slideToggle “bounces” multiple times on resize












1















I have a little problem with a simple jQuery script (I'm not an expert):



My requirements:



1) I have multiple elements that are made of
- a title
- a body



2) For a screen size > 768px, all the elements are visibile



3) For a screen size =< 768px I want to emulate the Bootstrap Collapse behavior, so when you click on the title, the "body" of the element, i.e. <div class="panel--collapsible" id="panel1"> becomes visible. The body of the element is not visible at the beginning by default.



I post here the code I wrote so far






$(document).ready(function() {
toggleDivOnMobile();
window.addEventListener('resize', function() {

toggleDivOnMobile();
});

});

function toggleDivOnMobile() {
$('.par-title--collapsible').click(function(e) {
e.preventDefault();
var currentAttrValue = $(this).attr('href');
var content = $(currentAttrValue);
if (window.outerWidth <= 768) {
content.slideToggle("slow");
}
});
return false;
}

.panel--collapsible {
display: none;
}

@media screen and (min-width:769px) {
.panel--collapsible {
display: block!important;
}
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="par1" class="collapsible">
<h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
<div class="panel--collapsible" id="panel1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>

<div id="par2" class="collapsible">
<h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
<div class="panel--collapsible" id="panel2">
<p>Cuius et cetera</p>
</div>
</div>





My problem is: after resizing the window, the collapse works, but it "bounces" multiple times.



You can simulate the behavior by resizing the window.



Thank you for your help;of course if you need more information, write me a comment :)










share|improve this question



























    1















    I have a little problem with a simple jQuery script (I'm not an expert):



    My requirements:



    1) I have multiple elements that are made of
    - a title
    - a body



    2) For a screen size > 768px, all the elements are visibile



    3) For a screen size =< 768px I want to emulate the Bootstrap Collapse behavior, so when you click on the title, the "body" of the element, i.e. <div class="panel--collapsible" id="panel1"> becomes visible. The body of the element is not visible at the beginning by default.



    I post here the code I wrote so far






    $(document).ready(function() {
    toggleDivOnMobile();
    window.addEventListener('resize', function() {

    toggleDivOnMobile();
    });

    });

    function toggleDivOnMobile() {
    $('.par-title--collapsible').click(function(e) {
    e.preventDefault();
    var currentAttrValue = $(this).attr('href');
    var content = $(currentAttrValue);
    if (window.outerWidth <= 768) {
    content.slideToggle("slow");
    }
    });
    return false;
    }

    .panel--collapsible {
    display: none;
    }

    @media screen and (min-width:769px) {
    .panel--collapsible {
    display: block!important;
    }
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="par1" class="collapsible">
    <h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
    <div class="panel--collapsible" id="panel1">
    <p>Lorem ipsum dolor sit amet</p>
    </div>
    </div>

    <div id="par2" class="collapsible">
    <h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
    <div class="panel--collapsible" id="panel2">
    <p>Cuius et cetera</p>
    </div>
    </div>





    My problem is: after resizing the window, the collapse works, but it "bounces" multiple times.



    You can simulate the behavior by resizing the window.



    Thank you for your help;of course if you need more information, write me a comment :)










    share|improve this question

























      1












      1








      1








      I have a little problem with a simple jQuery script (I'm not an expert):



      My requirements:



      1) I have multiple elements that are made of
      - a title
      - a body



      2) For a screen size > 768px, all the elements are visibile



      3) For a screen size =< 768px I want to emulate the Bootstrap Collapse behavior, so when you click on the title, the "body" of the element, i.e. <div class="panel--collapsible" id="panel1"> becomes visible. The body of the element is not visible at the beginning by default.



      I post here the code I wrote so far






      $(document).ready(function() {
      toggleDivOnMobile();
      window.addEventListener('resize', function() {

      toggleDivOnMobile();
      });

      });

      function toggleDivOnMobile() {
      $('.par-title--collapsible').click(function(e) {
      e.preventDefault();
      var currentAttrValue = $(this).attr('href');
      var content = $(currentAttrValue);
      if (window.outerWidth <= 768) {
      content.slideToggle("slow");
      }
      });
      return false;
      }

      .panel--collapsible {
      display: none;
      }

      @media screen and (min-width:769px) {
      .panel--collapsible {
      display: block!important;
      }
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="par1" class="collapsible">
      <h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
      <div class="panel--collapsible" id="panel1">
      <p>Lorem ipsum dolor sit amet</p>
      </div>
      </div>

      <div id="par2" class="collapsible">
      <h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
      <div class="panel--collapsible" id="panel2">
      <p>Cuius et cetera</p>
      </div>
      </div>





      My problem is: after resizing the window, the collapse works, but it "bounces" multiple times.



      You can simulate the behavior by resizing the window.



      Thank you for your help;of course if you need more information, write me a comment :)










      share|improve this question














      I have a little problem with a simple jQuery script (I'm not an expert):



      My requirements:



      1) I have multiple elements that are made of
      - a title
      - a body



      2) For a screen size > 768px, all the elements are visibile



      3) For a screen size =< 768px I want to emulate the Bootstrap Collapse behavior, so when you click on the title, the "body" of the element, i.e. <div class="panel--collapsible" id="panel1"> becomes visible. The body of the element is not visible at the beginning by default.



      I post here the code I wrote so far






      $(document).ready(function() {
      toggleDivOnMobile();
      window.addEventListener('resize', function() {

      toggleDivOnMobile();
      });

      });

      function toggleDivOnMobile() {
      $('.par-title--collapsible').click(function(e) {
      e.preventDefault();
      var currentAttrValue = $(this).attr('href');
      var content = $(currentAttrValue);
      if (window.outerWidth <= 768) {
      content.slideToggle("slow");
      }
      });
      return false;
      }

      .panel--collapsible {
      display: none;
      }

      @media screen and (min-width:769px) {
      .panel--collapsible {
      display: block!important;
      }
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="par1" class="collapsible">
      <h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
      <div class="panel--collapsible" id="panel1">
      <p>Lorem ipsum dolor sit amet</p>
      </div>
      </div>

      <div id="par2" class="collapsible">
      <h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
      <div class="panel--collapsible" id="panel2">
      <p>Cuius et cetera</p>
      </div>
      </div>





      My problem is: after resizing the window, the collapse works, but it "bounces" multiple times.



      You can simulate the behavior by resizing the window.



      Thank you for your help;of course if you need more information, write me a comment :)






      $(document).ready(function() {
      toggleDivOnMobile();
      window.addEventListener('resize', function() {

      toggleDivOnMobile();
      });

      });

      function toggleDivOnMobile() {
      $('.par-title--collapsible').click(function(e) {
      e.preventDefault();
      var currentAttrValue = $(this).attr('href');
      var content = $(currentAttrValue);
      if (window.outerWidth <= 768) {
      content.slideToggle("slow");
      }
      });
      return false;
      }

      .panel--collapsible {
      display: none;
      }

      @media screen and (min-width:769px) {
      .panel--collapsible {
      display: block!important;
      }
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="par1" class="collapsible">
      <h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
      <div class="panel--collapsible" id="panel1">
      <p>Lorem ipsum dolor sit amet</p>
      </div>
      </div>

      <div id="par2" class="collapsible">
      <h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
      <div class="panel--collapsible" id="panel2">
      <p>Cuius et cetera</p>
      </div>
      </div>





      $(document).ready(function() {
      toggleDivOnMobile();
      window.addEventListener('resize', function() {

      toggleDivOnMobile();
      });

      });

      function toggleDivOnMobile() {
      $('.par-title--collapsible').click(function(e) {
      e.preventDefault();
      var currentAttrValue = $(this).attr('href');
      var content = $(currentAttrValue);
      if (window.outerWidth <= 768) {
      content.slideToggle("slow");
      }
      });
      return false;
      }

      .panel--collapsible {
      display: none;
      }

      @media screen and (min-width:769px) {
      .panel--collapsible {
      display: block!important;
      }
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="par1" class="collapsible">
      <h2><a href="#panel1" class="par-title--collapsible">Title 1</a></h2>
      <div class="panel--collapsible" id="panel1">
      <p>Lorem ipsum dolor sit amet</p>
      </div>
      </div>

      <div id="par2" class="collapsible">
      <h2><a href="#panel2" class="par-title--collapsible">Title 2</a></h2>
      <div class="panel--collapsible" id="panel2">
      <p>Cuius et cetera</p>
      </div>
      </div>






      javascript jquery slidetoggle






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 14 '18 at 13:32









      Riccardo De ContardiRiccardo De Contardi

      1,176313




      1,176313
























          1 Answer
          1






          active

          oldest

          votes


















          0














          The problem is you're calling toggleDivOnMobile, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.



          The solution would be to set some external variable and only attach your event listeners once, like so:



          var isMobile = false;

          $(document).ready(function() {
          toggleDivOnMobile();
          handleWindowResize();

          window.addEventListener('resize', function() {
          handleWindowResize();
          });
          });

          function handleWindowResize() {
          isMobile = window.outerWidth <= 768;
          }

          function toggleDivOnMobile() {
          $('.par-title--collapsible').click(function(e) {
          e.preventDefault();
          var currentAttrValue = $(this).attr('href');
          var content = $(currentAttrValue);
          if (isMobile) {
          content.slideToggle("slow");
          }
          });
          return false;
          }


          There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.



          EDIT



          You may also want to place the isMobile check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.



          EDIT 2



          Updated code per OP request to include onload resize call.






          share|improve this answer


























          • Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as isMobile=false and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again

            – Riccardo De Contardi
            Nov 16 '18 at 9:27













          • @RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.

            – Sheng Slogar
            Nov 16 '18 at 9:38











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53301447%2fjquery-slidetoggle-bounces-multiple-times-on-resize%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          The problem is you're calling toggleDivOnMobile, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.



          The solution would be to set some external variable and only attach your event listeners once, like so:



          var isMobile = false;

          $(document).ready(function() {
          toggleDivOnMobile();
          handleWindowResize();

          window.addEventListener('resize', function() {
          handleWindowResize();
          });
          });

          function handleWindowResize() {
          isMobile = window.outerWidth <= 768;
          }

          function toggleDivOnMobile() {
          $('.par-title--collapsible').click(function(e) {
          e.preventDefault();
          var currentAttrValue = $(this).attr('href');
          var content = $(currentAttrValue);
          if (isMobile) {
          content.slideToggle("slow");
          }
          });
          return false;
          }


          There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.



          EDIT



          You may also want to place the isMobile check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.



          EDIT 2



          Updated code per OP request to include onload resize call.






          share|improve this answer


























          • Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as isMobile=false and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again

            – Riccardo De Contardi
            Nov 16 '18 at 9:27













          • @RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.

            – Sheng Slogar
            Nov 16 '18 at 9:38
















          0














          The problem is you're calling toggleDivOnMobile, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.



          The solution would be to set some external variable and only attach your event listeners once, like so:



          var isMobile = false;

          $(document).ready(function() {
          toggleDivOnMobile();
          handleWindowResize();

          window.addEventListener('resize', function() {
          handleWindowResize();
          });
          });

          function handleWindowResize() {
          isMobile = window.outerWidth <= 768;
          }

          function toggleDivOnMobile() {
          $('.par-title--collapsible').click(function(e) {
          e.preventDefault();
          var currentAttrValue = $(this).attr('href');
          var content = $(currentAttrValue);
          if (isMobile) {
          content.slideToggle("slow");
          }
          });
          return false;
          }


          There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.



          EDIT



          You may also want to place the isMobile check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.



          EDIT 2



          Updated code per OP request to include onload resize call.






          share|improve this answer


























          • Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as isMobile=false and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again

            – Riccardo De Contardi
            Nov 16 '18 at 9:27













          • @RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.

            – Sheng Slogar
            Nov 16 '18 at 9:38














          0












          0








          0







          The problem is you're calling toggleDivOnMobile, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.



          The solution would be to set some external variable and only attach your event listeners once, like so:



          var isMobile = false;

          $(document).ready(function() {
          toggleDivOnMobile();
          handleWindowResize();

          window.addEventListener('resize', function() {
          handleWindowResize();
          });
          });

          function handleWindowResize() {
          isMobile = window.outerWidth <= 768;
          }

          function toggleDivOnMobile() {
          $('.par-title--collapsible').click(function(e) {
          e.preventDefault();
          var currentAttrValue = $(this).attr('href');
          var content = $(currentAttrValue);
          if (isMobile) {
          content.slideToggle("slow");
          }
          });
          return false;
          }


          There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.



          EDIT



          You may also want to place the isMobile check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.



          EDIT 2



          Updated code per OP request to include onload resize call.






          share|improve this answer















          The problem is you're calling toggleDivOnMobile, which gets called at each window resize. By attaching your event handlers inside of that function, you end up getting multiple event handlers all trying to do the same thing, and they start fighting with each other.



          The solution would be to set some external variable and only attach your event listeners once, like so:



          var isMobile = false;

          $(document).ready(function() {
          toggleDivOnMobile();
          handleWindowResize();

          window.addEventListener('resize', function() {
          handleWindowResize();
          });
          });

          function handleWindowResize() {
          isMobile = window.outerWidth <= 768;
          }

          function toggleDivOnMobile() {
          $('.par-title--collapsible').click(function(e) {
          e.preventDefault();
          var currentAttrValue = $(this).attr('href');
          var content = $(currentAttrValue);
          if (isMobile) {
          content.slideToggle("slow");
          }
          });
          return false;
          }


          There are many other ways you can accomplish this, but that's a start. You can also look into the jQuery .off function if you wanted to dynamically add and remove event listeners based on the window size, but I wouldn't recommend that.



          EDIT



          You may also want to place the isMobile check in an external function, and call it on page load; a mobile browser (or any browser, really) won't trigger a resize event unless the browser is actually resized.



          EDIT 2



          Updated code per OP request to include onload resize call.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 16 '18 at 9:37

























          answered Nov 14 '18 at 14:52









          Sheng SlogarSheng Slogar

          912614




          912614













          • Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as isMobile=false and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again

            – Riccardo De Contardi
            Nov 16 '18 at 9:27













          • @RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.

            – Sheng Slogar
            Nov 16 '18 at 9:38



















          • Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as isMobile=false and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again

            – Riccardo De Contardi
            Nov 16 '18 at 9:27













          • @RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.

            – Sheng Slogar
            Nov 16 '18 at 9:38

















          Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as isMobile=false and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again

          – Riccardo De Contardi
          Nov 16 '18 at 9:27







          Sheng Slogar your answer is really good and almost perfect! :) the only drawback I found is that, as isMobile=false and changes only when resizing, if the initial window is already smaller than 768px, the toggle never works. It's easy to fix (I've already done) but I would ask you to update your answer to make it more complete, then I will gladly accept your answer. A big thank again

          – Riccardo De Contardi
          Nov 16 '18 at 9:27















          @RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.

          – Sheng Slogar
          Nov 16 '18 at 9:38





          @RiccardoDeContardi I did note that in the first edit and assumed that would be sufficient (not relevant to original question). I've updated my answer. Glad you've got things working.

          – Sheng Slogar
          Nov 16 '18 at 9:38




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53301447%2fjquery-slidetoggle-bounces-multiple-times-on-resize%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Xamarin.iOS Cant Deploy on Iphone

          Glorious Revolution

          Dulmage-Mendelsohn matrix decomposition in Python