Javascript正文OnClick

时间:2010-08-19 11:55:17

标签: javascript

我正在学习Javascript,我正在尝试创建一个简单的下拉菜单。我可以在顶部菜单的Google主页上看到我所需功能的一个示例,其中包含“更多”和“设置”下拉列表。特别是当您单击菜单时,菜单消失。

我需要在Javascript中的hideMenus函数中放置什么代码,以便在屏幕上的任何位置发生单击时隐藏可见的uls?

<!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>   

我不想使用jQuery。

3 个答案:

答案 0 :(得分:1)

看起来你的设置相当不错。您可能会遇到一些事件冒泡问题(有关更多信息,请查看PPK's Event Order Article)。这似乎超出了您当前问题的范围,所以我只会告诉您所要求的内容:

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';
        }
    }
}

首先,我们在页面上获得所有&lt; ul&gt;。然后,我们遍历所有这些,检查它是否是子菜单,以及它当前是否显示。如果两者都是真的,那么我们隐藏它。

此代码存在一些错误:

  • 如果uls有多个班级(class="animal submenu"),则不会隐藏菜单
  • 它将查看所有页面上的&lt; ul&gt ;.这不是很有效,但如果没有getElementsByClass的跨浏览器支持,这是唯一的方法。

这些不是很大的错误,特别是如果你只是用它来学习javascript,并且如果你密切控制你的代码(即没有其他开发人员正在研究它)。总而言之,这是一个很好的垫脚石。

将来,我建议使用addEvent - 一个相当常见的函数,允许您在不使用onclick="..."的情况下向元素添加事件处理程序。它有几种不同的实现,但它们(几乎)从你的角度来看都是一样的。以下是Dean Edwards's VersionJohn Resig's Version

的链接 祝你好运!

答案 1 :(得分:0)

这里或多或少是我们在网络应用中用于下拉菜单的逻辑:

<html>
<head>
    <title></title>
</head>
<body>
    <div style="position:relative;width:250px">
      <a id="link" href="javascript:" onclick="showDiv(this)">Show menu</a>
      <ul id="entries" style="display:none;background:#DEF;padding:0;margin:0">
        <li>item 1</li>
        <li>item 2</li>
      </ul>
      <input id="inp" style="position:absolute;left:-30px;width:0" />
    </div>

    <script>
        function showDiv(lnk){
            var entries = document.getElementById('entries'),
                inp = document.getElementById('inp'),
                nh = 'data-nohide';
            //show the entries
            entries.style.display = 'block';
            entries.removeAttribute(nh);
            inp.focus();
            //if mouse over, can't close it
            entries.onmouseover = function(){ 
                this.setAttribute(nh, true);
                inp.focus();
            }; 
            //if mouse out, can close it
            entries.onmouseout  = function(){ 
                this.removeAttribute(nh);
            };
            entries.onclick = function(e){
                //code when the user clicks on the menu...
                alert((e.target||e.sourceElement).innerHTML);
                this.style.display = 'none';
            };
            //if the user press ESC
            inp.onkeyup = function(e){
                if(e.keyCode === 27){
                    this.style.display = 'none';
                    this.removeAttribute(nh);
                }else{
                    //do something else with other keys(ie:down, up, enter)...
                    inp.focus();
                }
            };
            //click somewhere else input onblur
            inp.onblur = function(){
                if(!entries.getAttribute(nh)){
                    entries.style.display = 'none';
                    entries = inp = null;
                }
            };
        }
    </script>
</body>
</html>

诀窍是使用具有input的{​​{1}}字段,当它失去时,会触发focus并关闭菜单。

当用户点击菜单中的某个项目时,onblurmouseover会阻止mouseout触发。

要想像链接上的打开/关闭一样具有切换效果,我想需要2个相互隐藏的链接。

答案 2 :(得分:-1)

如果你点击身体,你可以在任何地方捕获一个点击。 由于javascript事件传播模型,如果您单击任何元素上的任何位置并且不会阻止事件传播,它将到达正文并隐藏菜单。

所以基本上这意味着你想捕捉身体onclick并让它隐藏菜单,所以当你点击页面的任何区域时,它会关闭菜单。

但这隐藏了一些不必要的行为 - 当您点击按钮显示菜单时,菜单将显示并快速隐藏(当事件到达正文时)。为了防止这种情况,当您单击显示菜单的按钮时,您将希望阻止事件传播(您可以在我下面发布的代码中看到它是如何工作的)。代码显示了您需要触摸的位置,以使其正常工作。

// this function stops event e or window.event if e is not present from 
// propagating to other elements.
function stop_event(e) {
   if(!e) {
      e = window.event;
   }
   if (e.stopPropagation) e.stopPropagation();
   e.cancelBubble = true;
   if (e.preventDefault) e.preventDefault();
   e.returnValue = false;
   return false;
}

// now you just hide all the menus in your hideMenus
function hideMenus()
{
    //pseudocode!
    for all visible menus - hide // or if you want you can hide all menus, 
                                 // the hidden will remain hidden
}

现在是重要的一部分。

function menu(id) {     
    // your stuff here
    stop_event(); // this will stop the event going down to the body 
                  // and hiding it after showing it
                  // this means it will not flicker like: show-hide
}  

最后是你的整个UL元素:

//partly pesudocode
ul.onclick = function() { stop_event(); }

再次解释这是做什么的:

第一。您将hideMenu函数挂钩到body.onclick。这意味着如果我们不停止事件,它将始终隐藏菜单。

第二。单击菜单按钮时,显示菜单,然后我们停止事件进入正文。这样,body.onclick将不会触发,并且在我们打开它之后它不会立即隐藏菜单。

第三。 ul.onclick意味着当我们点击它时菜单不会隐藏(虽然如果你想在单击菜单本身时隐藏菜单,你可以删除这部分)。