这是最好的方法吗?

时间:2010-02-22 20:18:02

标签: javascript jquery

我有一个导航栏,有两个下拉列表(如嵌套的ul)。我正在尝试在单击其父级时切换子视图。或者在单击另一个父项时隐藏一个子视图。这是标记:

<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的新手,我想知道是否有一种不那么冗长的方式来完成我上面要做的事情。

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

3 个答案:

答案 0 :(得分: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();
  })
})

答案 1 :(得分:0)

嗯,有几种方法可以让您更轻松地维护代码。这是一个简单的例子:

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

 $('ul.subnav').hide();
 subnav.toggle();
});

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

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

编辑:这与前一个答案显然相似:P

答案 2 :(得分: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中获取新元素。根据我的理解,链接在遍历已找到的元素时更有效,而不是获取新元素。

.end()将你的链恢复回上一个找到的元素,所以当我说.closest(“blah”)。find(“blah2”)时,我会深入两级。 .end()。end()会将我带回原始项目(this),以便我可以在其下面找到特定的subnav。