1

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);
  });
});

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for quick response. Unfortunately, it can't be the solution. I gave the "li" element special class name so the event handler binds only to it and it still reacts the same (unpredictable) way - sometimes toggle sometimes doesn't.
Don't know what you mean. I took the code into a JSFiddle jsfiddle.net/wu1unvek and it works like a charm for me. How does it go wrong for you?
Hi Joachim. Have a look at this screencast I recorded - it explains everything. For me it behaves weird - but it is way beyond my knowledge of jQuery. screencast-o-matic.com/watch/cDieQuiUA1 Seems like $(window).resize() is a problem here - you were saying there is another way of doing it. Could you give me a hint on how to avoid this behavior I would totally appreciate it. However thanks a lot for your time.
Is it, that you still use .resize() to setup an event handler? That would be a problem. I will add an example for my remark about resize() in my answer to make it more clear, what I meant.
Hi Joachim, thank you a lot for help with this. I'll solve this problem as you suggest - work really nice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.