How to hide a visible sub-menu by clicking on another JS menu?

Asked

Viewed 5,931 times

12

I have the script below to use in a menu. It changes the visibility of a specific element by its ID. Clicking on a main menu opens a submenu.

Is there any way to change the script so that when clicking another menu the previous submenu closes? Currently both are getting open.

<script type="text/javascript">
    function toggle_visibility(id) {
        var e = document.getElementById(id);
        if(e.style.display == 'block')
            e.style.display = 'none';
        else
            e.style.display = 'block';
        }
</script>

<a href="#" onclick="toggle_visibility('menu1');">
    <p>Menu Um</p>
</a>
<div id="menu1" style="display:none;">
    <ul>
        <li>Item Um</li>
        <li>Item Dois</li>
        <li>Item Três</li>
    </ul>
</div>

<a href="#" onclick="toggle_visibility('menu2');">
    <p>Menu Dois</p>
</a>
<div id="menu2" style="display:none;">
    <ul>
        <li>Item Um</li>
        <li>Item Dois</li>
        <li>Item Três</li>
    </ul>
</div>

2 answers

9


The quickest way to fix your code is to add a for loop to make all menus invisible and then show only what should be visible:

function toggle_visibility(id) {
    var e = document.getElementById(id);
    var visivel = e.style.display == 'block';
    var menus = document.querySelectorAll('[id^=menu]');
    for (var i = 0; i < menus.length; i++) {
        menus[i].style.display = 'none';
    };
    if (visivel) e.style.display = 'none';
    else e.style.display = 'block';
}

to your role. And by the way @Bacchus pointed with this addition can be removed the if() that becomes redundant and leaves alone: e.style.display = 'block'; (I updated the demo)

Demo


My suggestion would remove the mixed script in HTML and use javascript only:

var links = document.querySelectorAll('[id^=tituloMenu]');
for (var i = 0; i < links.length; i++) {
    links[i].addEventListener('click', toggle_visibility);
}

function toggle_visibility(e) {
    e.preventDefault(); //por precaução
    var idDestino = this.id.split('tituloMenu')[1];
    var el = document.getElementById('menu' + idDestino);
    var visivel = el.style.display == 'block';
    var menus = document.querySelectorAll('[id^=menu]');
    for (var i = 0; i < menus.length; i++) {
        menus[i].style.display = 'none';
    }
    if (visivel) el.style.display = 'none';
    else el.style.display = 'block';
}

Demo

Version with jQuery
Version with Mootools

  • Works Perfectly. Only it has a detail when updating does not come back with the previous menu that is Selected.

0

Your code was almost correct. The error was in the value assignment in the display variable. Look at mine below. Works perfectly.

function aparece(id){
    var e = document.getElementById(id);
    if(e.style.display == "none"){
        e.style.display="block";
    }else{
        e.style.display="none";
    }
}

I still used onmouseover and onmouseout to identify when the mouse is on or off the element, without the need to click. Get more sweaty :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.