How to hide a visible submenu when clicking another menu in JS?

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 on another menu the previous submenu close? They are currently getting both 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>
    
asked by anonymous 23.01.2014 / 21:45

2 answers

9

The fastest way to fix your code is to add a for loop to bring all the 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';
}

its function. And already I already have the @Bacco pointed out with this addition you can remove the if() that becomes redundant and leave only: e.style.display = 'block'; (I updated the demo)

Demo

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

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
MooTools Version

    
23.01.2014 / 21:52
0

Your code was almost correct. The error was in assigning value in the display variable. Look at mine below. It 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've still used onmouseover and onmouseout to identify when the mouse is on or off the element, without clicking. It gets softer:)

    
27.06.2014 / 21:47