Search code examples
javascriptjqueryhtmlcsstoggleclass

Toggle Class on cilck based on browser width (resize) via jQuery


I have a button with toggle class attached to it - and it should work only when the borwser size is below 1200px. It works after refresh but somehow when I resize the window it sometimes works and sometimes doesn't - can't see the pattern. I see on the dev tools the the element is higlighted (so hte script is doing something) but I doesn't toggle the class. Tried to change it to addClass/removeClass but the result is the same. Any advice how to make it work would be much appreciated.

CodePen: http://codepen.io/miunik/pen/oLWOLY

HTML:

<ul class="level-1">
  <li class="btn">1 level item
    <ul class="level-2">
      <li>2 level item</li>
      <li>2 level item</li>
      <li>2 level item</li>
      <li>2 level item</li>
    </ul>
  </li>
</ul>

CSS

ul.level-2 {
  display: none;
}

ul.level-2.open {
  display: block;
}

jQuery:

$(document).ready(function() {
  function setNav() {
    if (window.outerWidth < 1200) {
      $('.btn').on({
        click: function() {
          $(this).children('.level-2').toggleClass('open');
        }
      });
    }
  }
  setNav()
  $(window).resize(function() {
    setNav();
    console.log(window.outerWidth);
  });
});

Solution

  • The problem with your code is, that you bind a lot of event handlers: every time the window resize event occurs, each <li> tag (not only the one in level 1) gets a new one. So it depends on the number of event handlers if toggleClass() actually toggles or doesn't.

    I would only bind one handler, preferably on the document in conjunction with a selector which identifies only the <li> tags directly below .level-1 and ask for the screen size in this handler. You don't even need a resize handler for that.

    $(document).ready(function() {
      $(document).on("click", ".btn", function () {
        if (window.outerWidth < 1200) {
          $(this).children('.level-2').toggleClass('open');
        }
      });
    });
    

    See a working example here: https://jsfiddle.net/wu1unvek/

    It might be that you want a resize() handler anyway to remove the open class if the window gets larger:

    $(window).resize(function () {
      if (window.outerWidth >= 1200) {
        $(".level-2").removeClass("open");
      }
    });
    

    EDIT: Adapted to modified question code: Use .btn instead of .level-1 > li

    EDIT 2: Added example for resize() resetting the open class if window gets larger