This script should cyclically show and hide the menu when the button is pressed:

$(".menu-btn:first").click(switchMenu); function switchMenu(){ var menu = $(".menu:first"); if (!menu.hasClass('menu-show')){ menu.addClass('menu-show'); } else { menu.removeClass('menu-show'); } }; 

I get into if (i.e., not else ) each time I press a button, and not every other time. With the help of alert I made sure that after adding the menu-show class, the menu-show variable is not updated. Why is that?

  • This script is located immediately after the HTML code (suppose I am so comfortable in this task).
  • Outside, the addClass and removeClass functions work, which means that there is no error in the rows with these methods.
  • I read several sources, but did not clearly understand what the difference between switchMenu() and swhitchMenu . It was experimentally established that in this script, when changing switchMenu to switchMenu() function is invoked without pressing a button, the menu is shown, and after pressing the button, the program is moved to else . I absolutely do not understand what is happening.
  • But the most interesting thing: if after the function switchMenu() add menu.removeClass('menu-show'); then the GoogleChrome debugger, of course, will Uncaught ReferenceError: menu is not defined error Uncaught ReferenceError: menu is not defined , but the button will work correctly!

Please explain the behavior of this script.


Update And here is the reason: the function following switchMenu() . This function ( switchMenu ) removes the menu only when the button is pressed, and the function indicated below, when clicked outside the menu, to any place.

 $(function($){ $(document).mouseup(function (e){ var menu = $(".menu"); if (!menu.is(e.target) && menu.has(e.target).length === 0) { $(".menu").removeClass('menu-show'); } }); }); 

    1 answer 1

    Pretty weird behavior.

    1. Everything is logical here, you need to pass the function itself, which will be called when an event occurs, and not its call — everything is correct here;

    2. Here, too, all right, because menu declared inside the function and outside the function when accessing the variable there will be an error that it is not declared.

    Your example works great:

     $(document).ready(function() { $(".menu-btn:first").click(switchMenu); function switchMenu() { var menu = $(".menu:first"); if (!menu.hasClass('menu-show')) { menu.addClass('menu-show'); } else { menu.removeClass('menu-show'); } }; }); 
     .menu { display: none; } .menu-show { display: block; } 
     <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <nav class="menu">menu</nav> <button class="menu-btn">toggle menu</button> 

    • Probably, the reason is that your code is inside '$ (document) .ready (function () {', but I don’t. I understand how to fix the error, but the theory is not clear with the behavior of the function. - Gleb sides
    • And without the $ (document) .ready (function () {}) wrapper, this code should work fine. Perhaps the error is related to the html code - saaaaaaaaasha
    • one
      Found the reason. The fact is that this function conflicts with another one that was added to the question. `function switchMenu ()` removes the menu only when the button is pressed, but I added another function that does the same thing when clicking outside the menu field. - Bokov Gleb