Hello! I'm trying to build a menu with drop-down blocks and I have a little difficulty.

The principle is this, from HTML we take the attribute data in which the id of the block is registered, which we hide / display through jQuery. Two questions: how to prevent hiding a .navbar-dropdown-content block when clicking on itself (it closes because it is a child of the block I set this function for) and how to organize block concealment when clicking on any other place on the page?

<span class="navbar-dropdown" data-dropdown-id="navbar-dropdown-user"> Первая кнопка <div class="navbar-dropdown-content" id="navbar-dropdown-user"> Контент </div> </span> <span class="navbar-dropdown" data-dropdown-id="navbar-dropdown-user2"> Вторая кнопка <div class="navbar-dropdown-content" id="navbar-dropdown-user2"> Контент 2 </div> </span> (function ($) { 'use strict'; $(document).ready(function(){ $(".navbar-dropdown").click(function(){ var link = $(this); var dropdown_id = "#" + $(link).data("dropdown-id"); $.fn.dropdownOn = function() { $(link).addClass("is-active"); $(dropdown_id).show(); $(".navbar-dropdown").not(link).removeClass("is-active"); $(".navbar-dropdown-content").not(dropdown_id).hide(); }; $.fn.dropdownOff = function() { $(link).removeClass("is-active"); $(dropdown_id).hide(); }; if ($(link).hasClass("is-active")) { $(this).dropdownOff(); } else { $(this).dropdownOn(); }; }); }); })(jQuery); 

    2 answers 2

     (function($) { 'use strict'; $(document).ready(function() { // организовать сокрытие блока при клике на любое другое место в странице $(document).click(function(e) { if (!$(e.target).hasClass("navbar-dropdown") && $(e.target).closest(".navbar-dropdown").length == 0) $(".navbar-dropdown-content").hide(); }); $(".navbar-dropdown").click(function(e) { // запретить скрытие блока .navbar-dropdown-content при клике на самого себя if ($(e.target).hasClass("navbar-dropdown-content")) return; var link = $(this); var dropdown_id = "#" + $(link).data("dropdown-id"); var dropdownOn = function() { $(link).addClass("is-active"); $(dropdown_id).show(); $(".navbar-dropdown").not(link).removeClass("is-active"); $(".navbar-dropdown-content").not(dropdown_id).hide(); }; var dropdownOff = function() { $(link).removeClass("is-active"); $(dropdown_id).hide(); }; if ($(link).hasClass("is-active")) { dropdownOff(); } else { dropdownOn(); }; }); }); })(jQuery); 
     .navbar-dropdown-content{ display:none; } 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <span class="navbar-dropdown" data-dropdown-id="navbar-dropdown-user"> Первая кнопка <div class="navbar-dropdown-content" id="navbar-dropdown-user"> Контент </div> </span> <span class="navbar-dropdown" data-dropdown-id="navbar-dropdown-user2"> Вторая кнопка <div class="navbar-dropdown-content" id="navbar-dropdown-user2"> Контент 2 </div> </span> 

      I do not understand much, just learning. Therefore, the answer is not the most useful, but still: I don’t really understand why so much code :) I will describe how I wrote menus for myself:

      1) On hover:

       $(function () { $("div.wrap").hover(function () { $(this).find('.foot').stop(true).slideToggle(); }); }); 

      The menu block in the markup looks like this (the class ".foot" in styles is set to "display: none;":

       <div class="wrap"> <div class="head"></div> <div class="foot"></div> </div> 

      2) By clicking the menu button under the same markup:

       $(function () { $(".head").click(function (e) { $(".foot").not($(this).next()).slideUp(); $(this).next().slideToggle(); }); $(document).click(function (e) { if (!$(".wrap").is(e.target) && $(".wrap").has(e.target).length === 0) { $(".foot").slideUp(); } }); }); 

      I hope to help at least partially.

      • It’s pretty bold to stop an event on a specific element and immediately write a $(document).click . And if the page uses other scripts with similar logic - how do they know about clicks on the document? - Igor
      • You can pack everything into one .on handler, but then you will need to call it all the same on $ (document) and do a type check! Div.is (e.target). The function is easy to isolate, what it interferes with the rest? And did not understand much of the stop. Explain to the beginner :) - Roman Stoliarenko
      • You stop the click event in $("div.head").click , so the $(document).click does not get it. But you know that to click on the rest of the page, you need a document click handler. For this menu, everything is very good. - Igor
      • Imagine that in addition to the script for this menu, there is one more (or several) - in completely separate files, maybe even on other resources. These scripts do not know about each other. But each of them expects his handlers for $(document).click called. For them or for you, depending on the order of connection of scripts, these calculations will not be justified. - Igor
      • "so it doesn't get to the $ (document) .click handlers" "I don’t understand the way you think :) What stops it? I have 3 separate functions in the code called on the elements by the .click handler, which can be assembled into one with checks, but more readable. And they are not available outside of the DOM loading function, as far as I know :) - Roman Stoliarenko