2010-02-22 102 views
1

我有一个导航栏有两个下拉列表(作为嵌套ul的)。我试图切换subnavs时,其父母被点击。或者当另一个父母被点击时隐藏一个subnav。这里的标记:这是最好的方法吗?

<div id="nav-bar"> 
    <a href="#">A link</a> | 
    <ul> 
    <li id="feedback"> 
     <a href="javascript:void(0);">Feedback</a> 
     <ul class="subnav"> 
     <li><a href="#">Give us feedback</a></li> 
     </ul> 
    </li> 
    </ul> | 
    <a href="#">Another link</a> | 
    <ul> 
    <li id="location"> 
     <a href="javascript:void(0);">Pick your location</a> 
     <ul class="subnav"> 
     <li><a href="#">Los Angeles</a></li> 
     <li><a href="#">New York</a></li> 
     </ul> 
    </li> 
    </ul> 
</div> 

,代码:

//hide the subnavs and give them a little down arrow 
$('ul.subnav').hide().parent().append('<small>&#9660;</small>'); 

// show its subnav when clicked 
$('#nav-bar ul li').click(function() { 
    var subnav = $(this).children('ul.subnav'); 
    // hide the other's subnav if it's visible 
    if ($(this).attr('id') == 'location') { 
    subnav.toggle(); 
    $('li#feedback').children('ul.subnav').hide(); 
    } else { 
    subnav.toggle(); 
    $('li#location').children('ul.subnav').hide(); 
    } 
}); 

仍然是一个新手,JS和jQuery,我想知道是否有做到我想要一个更简洁的方式做以上。

编辑:一个更好的问题是,有没有办法做到这一点,而不必明确地给李的ID?

+1

你应该说你正在努力达到的目的..而不是让人们试图从你的代码中找出它。我们怎么知道你想要做的是你的代码是什么? – Layke 2010-02-22 20:19:19

+0

我试图切换subnavs,当其父母被点击。或者当另一个父母被点击时隐藏一个subnav。 – farkenfooken 2010-02-22 20:20:31

+0

Heed Laykes。你需要提供你想要做的事情的解释,特别是你不喜欢你目前如何做的事情。 – 2010-02-22 20:20:58

回答

1

一个更好的格式将是这样为你的HTML:

<ul id="nav-bar"> 
    <li><a href="#">A link</a> |</li> 
    <li> 
    <a href="#">Feedback</a> | 
    <ul class="subnav"> 
     <li><a href="#">Give us feedback</a></li> 
    </ul> 
    </li> 
    <li><a href="#">Another link</a> |</li> 
    <li> 
    <a href="#">Pick your location</a> | 
    <ul class="subnav"> 
     <li><a href="#">Los Angeles</a></li> 
     <li><a href="#">New York</a></li> 
    </ul> 
    </li> 
</ul> 

然后jQuery代码应该是这样的:

$(function(){ 
    var $nav = $("#nav-bar"), 
     $subnav = $nav.find("ul.subnav").hide(); 

    $nav.children('li:has(ul.subnav)').click(function(e){ 
    e.preventDefault(); 
    var $sub = $(this).children('ul.subnav').toggle(); 
    $subnav.not($sub).hide(); 
    }) 
}) 
+0

这更多是我想要做的。很棒。 我知道这是要求你解释很多,但你这样做的原因是什么?我做这件事的方式不理想,为什么? – farkenfooken 2010-02-22 20:31:38

+0

@fenkenfooken首先,我尝试使用语义标记(导致较少的标记),将导航描述为具有“子列表”的某些链接的“链接列表”。然后,在jQuery上,通过将结果集缓存在变量中,我加快了搜索时间(jQuery不必一遍又一遍地找到相同的项目)。最后,我使用了更复杂的jQuery选择器而不是类名或id来保持标记尽可能简单。如果需要,可以进一步简化。 – 2010-02-22 21:20:56

+0

感谢您花时间回复我的问题。 – farkenfooken 2010-02-22 21:55:43

0

嗯,有几个方法,你可以做维护你的代码更容易一点。这里有一个简单的例子:

​​

基本上,这将再次重新隐藏所有“subnav”的元素,然后显示被点击的一个。但是,这里的主要区别在于,您现在可以添加第三,第四,等等下拉菜单,或者更改ID而无需更改JavaScript。

您使用的HTML看起来相当不错,并且与“标准”导航菜单相似。

编辑:这显然是类似于以前的答案:P

+0

这对我来说代码更改量最少。 – farkenfooken 2010-02-22 21:57:25

+0

我应该注意到这并没有成功地切换你点击的李,只显示它。 – farkenfooken 2010-02-22 22:40:03

0

我摆脱了内嵌javascript:void(0)码这是不必要的。把你的链接链接到“#”。

你绝对不希望匹配这样的ID,它不能很好地扩展。取而代之的是,这样的事情应该工作(未经测试):

$('#nav-bar ul li').click(function() {  
    $(this) 
    //hide all subnavs 
    .closest("#nav-bar").find("ul.subnav").hide().end().end() 
    //show subnav under the li clicked 
    .find("ul.subnav").show();  
}); 

只要有可能,你想chain your jquery代码,这样你就不必从DOM每次抢到了新的元素。根据我的理解,在遍历已找到的元素时链更有效,而不是获取新的元素。 (“blah”)。find(“blah2”)我要深入两层。 .end()。end()会将我带回原始项目(this),以便我可以找到它下面的特定subnav。

+0

谢谢,我直到现在都不知道.end()。 – farkenfooken 2010-02-22 22:01:06