Menu 1
  • _Submenu a ...">

    Creating a drop-down menu from a simple list

    I have a current list:

    <ul>
       <li><a href="#">Menu 1</a></li>
       <li><a href="#">_Submenu a</a></li>
       <li><a href="#">_Submenu b</a></li>
       <li><a href="#">_Submenu c</a></li>
       <li><a href="#">Menu 2</a></li>
       <li><a href="#">Menu 3</a></li>
       <li><a href="#">_Submenu x</a></li>
       <li><a href="#">_Submenu y</a></li>
       <li><a href="#">Menu 4</a></li>
    </ul>
    

    How can I use jQuery to create a dropdown menu.

      <ul>
          <li><a href="#">Menu 1</a>
             <ul>
               <li><a href="#">_Submenu a</a></li>
               <li><a href="#">_Submenu b</a></li>
               <li><a href="#">_Submenu c</a></li>
             </ul>
          </li>
          <li><a href="#">Menu 2</a></li>
          <li><a href="#">Menu 3</a>
             <ul>
                <li><a href="#">_Submenu x</a></li>
                <li><a href="#">_Submenu y</a></li>
             </ul>
          </li>
          <li><a href="#">Menu 4</a></li>
     </ul>
    

    This means that some elements after the main element that "_" will be added as drop-down elements for the main element. Thank you for your help.

    +4
    source share
    3 answers

    You can achieve the effect you are looking for using the following logic.

    • Create a shared cache variable to hold the previous top-level menu.
    • Scroll through all the items in the menu list to see if the text begins with an underline.
      • If so, add this to the previous top-level menu.
      • , .
    • , (.find('ul:empty').remove()).

    Native DOM API jQuery- , :

    • $(this).append('<ul></ul>') $(this) . , DOM API this.appendChild($('<ul>')[0]), . ...
    • , jQuery , DOM API. .: youmightnotneedjquery.com

    var prev;
    $('.menu li').each(function(){
        if(/^_/.test(this.textContent) && prev) {
            prev.appendChild(this);
        } else {
            prev = this.appendChild($('<ul>')[0]);
        }
    }).find('ul:empty').remove();
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <ul class="menu">
       <li><a href="#">Menu 1</a></li>
       <li><a href="#">_Submenu a</a></li>
       <li><a href="#">_Submenu b</a></li>
       <li><a href="#">_Submenu c</a></li>
       <li><a href="#">Menu 2</a></li>
       <li><a href="#">Menu 3</a></li>
       <li><a href="#">_Submenu x</a></li>
       <li><a href="#">_Submenu y</a></li>
       <li><a href="#">Menu 4</a></li>
    </ul>

    HTML:

    <ul class="menu">
        <li><a href="#">Menu 1</a>
            <ul>
                <li><a href="#">_Submenu a</a></li>
                <li><a href="#">_Submenu b</a></li>
                <li><a href="#">_Submenu c</a></li>
            </ul>
        </li>
        <li><a href="#">Menu 2</a></li>
        <li><a href="#">Menu 3</a>
            <ul>
                <li><a href="#">_Submenu x</a></li>
                <li><a href="#">_Submenu y</a></li>
            </ul>
        </li>
        <li><a href="#">Menu 4</a></li>
    </ul>
    
    +8

    // Create custom selectors
    $.extend($.expr[':'], {
      startsWith: function(e, i, m) {  
        return $(e).text().trim().indexOf(m[3]) === 0;
      }
    });
    
    $("li:not(:startsWith(_))").each(function(){  // LI that are not _Sub
      if($(this).next("li:startsWith(_)").length) // If my next() is _Sub, start grouping:
      $("<ul/>", {
        html: $(this).nextUntil("li:not(:startsWith(_))"),
        appendTo: this
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <ul>
      <li><a href="#">Menu 1</a></li>
      <li><a href="#">_Submenu a</a></li>
      <li><a href="#">_Submenu b</a></li>
      <li><a href="#">_Submenu c</a></li>
      <li><a href="#">Menu 2</a></li>
      <li><a href="#">Menu 3</a></li>
      <li><a href="#">_Submenu x</a></li>
      <li><a href="#">_Submenu y</a></li>
      <li><a href="#">Menu 4</a></li>
    </ul>

    HTML:

    <ul>
      <li>
        <a href="#">Menu 1</a>
        <ul>
          <li><a href="#">_Submenu a</a></li>
          <li><a href="#">_Submenu b</a></li>
          <li><a href="#">_Submenu c</a></li>
        </ul>
      </li>
      <li>
        <a href="#">Menu 2</a>
      </li>
      <li>
        <a href="#">Menu 3</a>
        <ul>
          <li><a href="#">_Submenu x</a></li>
          <li><a href="#">_Submenu y</a></li>
        </ul>
      </li>
      <li>
        <a href="#">Menu 4</a>
      </li>
    </ul>
    
    +4

    $('.group1').wrapAll('<ul></ul>');
    $('.group2').wrapAll('<ul></ul>');
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <ul>
      <li><a href="#">Menu 1</a>
      </li>
      <li class='group1'><a href="#">_Submenu a</a>
      </li>
      <li class='group1'><a href="#">_Submenu b</a>
      </li>
      <li class='group1'><a href="#">_Submenu c</a>
      </li>
      <li><a href="#">Menu 2</a>
      </li>
      <li><a href="#">Menu 3</a>
      </li>
      <li class='group2'><a href="#">_Submenu x</a>
      </li>
      <li class='group2'><a href="#">_Submenu y</a>
      </li>
      <li><a href="#">Menu 4</a>
      </li>
    </ul>

    Use . wrap ()

    Description: Wrap an HTML structure around each element in a set of consistent elements.

    Use . wrapAll ()

    Description: Wrap an HTML structure around all elements in a set of consistent elements.

    +1
    source

    Source: https://habr.com/ru/post/1617360/


    All Articles