代码之家  ›  专栏  ›  技术社区  ›  juFo

jQuery在除current之外的h元素之后折叠ul

  •  2
  • juFo  · 技术社区  · 6 年前

    对于这个网站,我有一个菜单,通过 MIIS

    <h4><a>title</a></h4>
    <ul>
      <li><a>foo</a></li>
      <li> <a>foo</a>
        <ul>
          <li><a>sub</a></li>
        </ul>
      </li>
     <li><a>foo</a></li>
    </ul>
    
    <h4><a>other title</a></h4>
    
    <ul>
      <li><a>other…</a></li>
      ...
    </ul>
    

    默认情况下,我只想显示h4标题,而不是下面的列表。仅当您单击标题时,它才显示ul内容(仅显示下面的第一级)。点击另一个标题应隐藏其他部分的其他ul内容,并在标题下方显示当前ul。

    我现在被common.js中的折叠代码困住了,所有东西都会被折叠:

    $('.miis-toc > ul > li > a').filter(function(){
            return ($(this).attr('href') != '');
        }).parent().find('ul > li').hide();
    
        $('.miis-toc > h4').filter(function(){
              return ($(this).attr('href') != '');
         }).parent().find('ul').hide();
    
    
    currLink.parentsUntil('.miis-toc > ul').last().find('li').show()
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Dacre Denny    6 年前

    如果我正确地理解了您的问题,并且理解了菜单HTML的定义和结构,那么一个可能的解决方案可能是像这样修改jQuery:

    // Hide all ul sublists that are direct children of .miis-toc by
    // default
    $('> ul', '.miis-toc').hide()
    
    // Listen for click event on h4 elements that are directly under
    // .miis-toc
    $('> h4', '.miis-toc').click(function() {
    
      // Hide all ul sublists that are direct children of .miis-toc
      $('> ul', '.miis-toc').hide()
    
      // Show the ul sublist that is "after" the h4 that has been clicked
      // (ie this)
      $('+ ul', this).show()
    
      // Prevent default click behaviour
      return false; 
    })
    

    请看一个 completed example of this solution on jsFiddle

    更新的答案

    对于下面评论中澄清的新细节,以下解决方案应满足所有要求。请注意,JS代码将“预切换”菜单UL或sub UL基于URL匹配(即基于浏览器URL路径名)。

    您需要更新HTML,如下所示:

    <div class="miis-toc">
      <h4><a href="/title/">title</a></h4>
      <!-- If path name is /title/, entire tree to this point will be 
           preopened to here -->
      <ul>
        <li><a>foo</a></li>
        <li><a href="/foo/">foo</a> 
          <!-- If path name is /foo/, entire tree to this point will 
               be preopened to here -->
          <ul>
            <li><a>sub</a></li>
          </ul>
        </li>
       <li><a>foo</a></li>
      </ul>
    
      <h4><a>other title</a></h4>
      <ul>
        <li><a>other…</a></li>
        ...
      </ul>
    </div>
    

    更新后的jQuery如下:

    // This code block sets up the menu when the page first loads, and
    // decides which UL or UL sublist to display based on current URL
    {
        // Hide all UL's that are under .miis-toc
      $('ul', '.miis-toc').hide()
    
      // Look for a UL sublist after an anchor with href matching our 
      // browsers current pathname
      var node = $('a[href="'+location.pathname+'"] + ul', '.miis-toc')
    
      // If not found, look for a UL after an h4 with child anchors href
      // matching our browsers current pathname
      if(node.length === 0) {
        var a = $('h4 a[href="'+location.pathname+'"]', '.miis-toc')
        node = $('+ ul', a.parent())
      }
    
      // If we have found a UL or UL sublist, we need to walk back up the 
      // "menu tree" and "show" each node (ie UL and/or UL sublist)
      if(node.length) {
        var parent = node 
        // When we reach to top of the menu (ie .miis-toc), terminate the
        // loop
        while(!parent.hasClass('miis-toc')) {
          parent.show()
          parent = parent.parent() 
        }
      }
    }
    
    // Listen for click event on h4 and nested li > a elements under
    // .miis-toc
    $('h4, li > a', '.miis-toc').click(function(event) {
    
      // Toggle (show/hide) adjacent ul sublist when clicked
      $('+ ul', this).toggle()
    
      // Prevent default click behaviour
      return false; 
    })