简体   繁体   中英

Show menu when i click on button and hide that when i click anywhere on the page or button

I have small dropdown profile menu with logout button etc. I need to show the menu when I click on the button and hide it when i click anywhere on page or on the button as well.

<div id='menu'>
    <ul>
        <li class='has-sub'> <a class="testbutton" id="userButton" onclick="dropdown()" href="#">
                            <span id="buttonText">User name</span> <span id="triangleDown">&#9662;</span>
                        </a>

            <ul id="submenu">
                <li class='has-sub'><a href='#'><span>Change password</span></a>
                </li>
                <li class='has-sub'><a href='logout.php?action=0'><span>Logout</span></a>
                </li>
            </ul>
        </li>
    </ul>
</div>

I used JavaScript. At this time menu is displayed on hidded only when I click on profile button. I also know how to start function using something like document.ready.

My not working code:

function dropdown() {
    if ($('#submenu').css('visibility') == 'hidden') {
        $('#submenu').css('visibility', 'visible');
    } else {
        $('#submenu').css('visibility', 'hidden');
    }
};

$(document).click(function (event) {
    if ($('#submenu').css('visibility') == 'visible') {
        $('#submenu').css('visibility', 'hidden');
    }
});

But when I combine this methods it does not works. So when I clicked on the button to open menu, nothing happened.

Sorry for my English :) Thanks for help in advance.

This has partly to do with something called event propagation. Put simply, this means that click events will register not only on the clicked element, but also on any parent or ancestor elements of that element.

So if you click a DIV, the event will also be registered on the BODY, because the DIV is inside the BODY. Put abstractly, if a kitchen is the scene of a crime, then the apartment that houses that kitchen is also the scene of a crime. One is inside the other.

This is prevented by preventing propagation - in jQuery, by running the stopPropagation() method of the evt object that is automatically passed to your event handler.

In any case, your situation can be greatly simplified.

var menu = $('#menu'), but = $('#menu_button');
$(document).on('click', '*', function(evt) {
    evt.stopPropagation(); //<-- stop the event propagating to ancestral elements
    if ($(this).is(but))   //<-- on button click, toggle visibility of menu
        menu.toggle();
    else if (!$(this).closest(menu).length) //<-- on click outside, hide menu
        menu.hide();
});

Assumption: I have assumed that the toggler button is targetable via the selector '#menu_button'. Update this as required. Also, the code should run inside a DOM-ready handler.

The code listens for clicks to any element. If it's registered on the button, the visible state of the menu is toggled. If it's to an element outside of the menu, the menu is hidden. (If, in the latter case, the menu is already hidden, this will have no effect.)

Here's a working JS Fiddle that demonstrates the approach.

Try this:

$(function() {

    $('.test-button').click(function(event) {
        event.stopPropagation();
        $('#submenu').toggle();
    });

    $('body').click(function() {
        var submenu = $('#submenu');
        if(submenu.is(":visible")) {
            submenu.hide();
        }
    })


});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM