Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript body OnClick

Tags:

javascript

I'm in the process of learning Javascript and I'm trying to create a simple dropdown menu. An example of my desired functionality can be seen on the google homepage in the top menu with the "more" and "settings" dropdown. Specifically when you click off the menu, the menu disappears.

What code do I need to place in the hideMenus function in Javascript to hide the visible uls when a click occurs anywhere on screen?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  

<head>  
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />  
<title>Untitled 1</title>  

<style type="text/css">  
a  
{  
    color:blue;  
}  

.info ul.submenu  
{  
    border: solid 1px #e0e0e0;  
    background-color: #fff;  
    position: absolute;  
    padding: 0;  
    z-index: 2;  
    display: none;  
}  

.info ul.submenu li  
{  
    display: block;  
    border-top: solid 1px #e0e0e0;  
    margin: 0px 10px 0 10px;  
}  

.info ul.submenu li a  
{  
    display: block;  
    padding: 7px 0px 6px 0;  
    color: #1177ee;  
    cursor:pointer;  
}  

</style>  

<script type="text/javascript">  

function hideMenus()
{
//TODO
}

function menu(id) {     
    var myLayer = document.getElementById(id);     

    myLayer.onblur = function() {       
        myLayer.style.display = 'none';   
    };   

    if (myLayer.style.display == "none" || myLayer.style.display == "") {     
        myLayer.style.display = "block";     
    } else {     
        myLayer.style.display = "none";     
    }     
}  

</script>  
</head>  

<body onclick="hideMenus();">  
<div class="info">     
     Some Text Boom A <a  onclick="menu('id1');">Link</a> | More text    
     <a onclick="menu('id2');">Another Link</a> | more text    
     <ul id="id1" class="submenu">     
       <li><a href="dfhdfh">A1</a></li>     
       <li><a href="aetjetjsd">A2 This is Long</a></li>     
       <li><a href="etetueb">A3</a></li>     
     </ul>     
    <ul id="id2" class="submenu">     
       <li><a href="dfhdfh">B1</a></li>     
       <li><a href="aetjetjsd">B2</a></li>     
       <li><a href="etetueb">B3</a></li>     
     </ul>     
  </div>    
</body>  
</html>   

I do not want to use jQuery.

like image 243
Jim Roboju Avatar asked Aug 19 '10 11:08

Jim Roboju


1 Answers

It looks like you have a pretty decent setup as-is. You'll likely run into some event bubbling problems (for more info, take a look at PPK's Event Order Article). That seems to be outside of the scope of your current question, so I'll just give you what you asked for:

hideMenus()
{
    var uls = document.getElementsByTagName('ul'), i;
    for (i = 0; i < uls.length; i++)
    {
        if (uls[i].className === 'submenu' && uls[i].style.display !== 'none')
        {
            uls[i].style.display = 'none';
        }
    }
}

First, we get all the <ul>'s on the page. Then, we loop through all of them, check to see if it's a submenu, and if it's currently displayed. If both are true, then we hide it.

There are a couple faults with this code:

  • If the uls have more than one class (class="animal submenu"), then it will not hide the menu
  • It will look through all the <ul>'s on the page. This isn't exactly efficient, but it's the only way to do it without cross-browser support for getElementsByClass.

These aren't huge faults, especially if you're only using this to learn about javascript, and if you closely control your code (i.e. no other developers are working on it). All in all, it's a good stepping stone.

In the future, I'd suggest using addEvent - a fairly common function that allows you to add event handlers to elements without using onclick="...". There are a couple different implementations of it, but they (almost) all work the same from your perspective. Here are links to Dean Edwards's Version and John Resig's Version

Good luck!

like image 172
Ryan Kinal Avatar answered Jan 01 '23 19:01

Ryan Kinal