adding more button for list in responsive navigation

vbl*_*nka 3 javascript jquery responsive-design

I have a navigation of lets say 12 items, and when resolution gets smaller items drop in a new line. I need to make that when an item doesn't fit on a navigation anymore it should put a "MORE" dropdown button on the right side of nav. and put that item that doesn't fit in a dropdown. If you don't understand me there is image below.

But the problem is that navigation items aren't always the same width because navigation items are generated from REST api.

I tryed to make jQuery script for calculating items width and adding them to navigation. Here is the script I created, I made it in a hurry so it's really bad.

I need to help on how to properly calculate items witdh and navigation width and calculating when to add items to navigation or remove items from navigation.

Here is image if you don't get it: http://img.hr/aagV

   

    /*
    * Here we check how many items can we put on the navigation bar
    * If item doesn't fit we clone it on the more dropdown button
    */
    function removeMany() {
        var i = $items.length - 1;

        if (itemsWidth > navWidth) {
            while (itemsWidth > navWidth) {
                $($items[i]).removeClass('first-level-item').addClass('second-level-item');
                dropdownItems.push($items[i]);
                $($items[i]).removeClass('showed');
                $items.pop();
                
                i--;
                getItemsWidth();
            }

            $nav.append($navMore);

            dropdownItems.reverse().forEach(function (element, index, array) {
                $('ul.second-level').append(element);
            });

            getItems();
        }
    }

    //If window is resized to bigger resolution we need to put back items on the navbar
    function addMany() {
        var i = dropdownItems.length - 1;

        if (dropdownItems.length != 0) {

            do {
                $('ul.first-level').append(dropdownItems.reverse()[i]);
                $items.push(dropdownItems[i]);
                dropdownItems.pop();

                i--;
                getItemsWidth();
            } while (itemsWidth < navWidth);

            $navMore.remove();

            $items.each(function (i) {
                $(this).addClass('first-level-item showed').removeClass('second-level-item');
            });

            if (!(dropdownItems != 0)) {
                return;
            } else {
                $nav.append($navMore);
            }


        }
    }

 
Run Code Online (Sandbox Code Playgroud)
body {
  margin: 0;
  padding: 0;
  border: 0; }

ul, li {
  margin: 0;
  padding: 0;
  list-style: none; }

ul.second-level li {
  display: block !important; }
ul.second-level li > a {
  color: black; }

a {
  color: #fff;
  text-decoration: none;
  text-transform: uppercase; }

.second-level-item a {
  color: #333 !important; }

.navigation {
  width: 960px;
  max-width: 100%;
  background: #211;
  color: #aaa;
  margin: 0 auto; }

.first-level .first-level-item {
  display: inline-block;
  padding: 10px; }
.first-level .item-more {
  display: inline-block; }
  .first-level .item-more .second-level-item {
    display: inline-block; }

.second-level {
  position: absolute;
  top: 100%;
  right: 0;
  width: 200px;
  background: #fff;
  padding: 10px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); }

.has-second-level {
  position: relative; }
  .has-second-level .second-level {
    display: none; }
  .has-second-level:hover {
    background: #fff;
    color: #000; }
    .has-second-level:hover .second-level {
      display: block; }

/*# sourceMappingURL=style.css.map */
Run Code Online (Sandbox Code Playgroud)
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>DropDown</title>

    <link rel="stylesheet" href="css/reset.css"/>
    <link rel="stylesheet" href="css/style.css"/>
</head>
<body>
    <nav class="navigation">

        <ul class="first-level">

            <li class="first-level-item showed"><a href="#">Introduction to Irish Culture</a></li>
            <li class="first-level-item showed"><a href="#">Cellular and Molecular Neurobiology</a></li>
            <li class="first-level-item showed"><a href="#">Guitar foundations</a></li>
            <li class="first-level-item showed"><a href="#">Startup Inovation</a></li>
            <li class="first-level-item showed"><a href="#">Astrophysics</a></li>


            <li class="first-level-item item-more has-second-level">
                <span> More </span>

                <ul class="second-level">

                </ul>

            </li>

        </ul>

    </nav>

    <script src="https://code.jquery.com/jquery-2.1.1.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Abh*_*lks 5

如果您有固定宽度的列表项,那么收集额外的列表项并将它们推送到单独的列表中很简单。这是一个简单的例子。解释在代码注释中。

全屏查看代码片段并尝试更改窗口宽度

也是一个小提琴 http : //jsfiddle.net/abhitalks/860LzgLL/

全屏 http : //jsfiddle.net/abhitalks/860LzgLL/embedded/result/

片段

var elemWidth, fitCount, fixedWidth = 120,  
    $menu = $("ul#menu"), $collectedSet;

// Assuming that the list-items are of fixed-width.

collect();
$(window).resize(collect);

function collect() {
    // Get the container width
    elemWidth = $menu.width();
  
    // Calculate how many list-items can be accomodated in that width
    fitCount = Math.floor(elemWidth / fixedWidth) - 1; 
  
    // Create a new set of list-items more than the fit count
    $collectedSet = $menu.children(":gt(" + fitCount + ")");
  
    // Empty the collection submenu and add the cloned collection set
    $("#submenu").empty().append($collectedSet.clone());    
}
Run Code Online (Sandbox Code Playgroud)
* { box-sizing: border-box; margin: 0; padding: 0; }
div { position: relative; background-color: #ccc; height: 32px; overflow: visible; }
ul#menu, ol { height: 32px; max-width: 80%; overflow: hidden; }
ul#menu > li, ol > li { display: block; float: left;  height: 32px; width: 120px; padding: 4px 8px; }
ol { position: absolute; right: 0; top: 0; overflow: visible; }
ol > li { min-width: 120px; }
ol ul { position: absolute; top: 120%; right: 10%; }
ol li ul > li { list-style: none; background-color: #eee; border: 1px solid gray; padding: 4px 8px;}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <ul id="menu">
        <li>Option One</li><li>Option Two</li><li>Option Three</li>
        <li>Option Four</li><li>Option Five</li><li>Option Six</li>
    </ul>
    <ol><li>Collected<ul id="submenu"></ul></li></ol>
</div>
Run Code Online (Sandbox Code Playgroud)


更新:

这是关于您对列表项的不同/可变宽度的查询。会有微小的变化。

也是一个小提琴 http : //jsfiddle.net/abhitalks/tkbmcupt/1/

全屏 http : //jsfiddle.net/abhitalks/tkbmcupt/1/embedded/result/

片段

var elemWidth, fitCount, varWidth = 0, ctr, $menu = $("ul#menu"), $collectedSet;

// Get static values here first
ctr = $menu.children().length;         // number of children will not change
$menu.children().each(function() {
    varWidth += $(this).outerWidth();  // widths will not change, so just a total
});

collect();  // fire first collection on page load
$(window).resize(collect); // fire collection on window resize

function collect() {
    elemWidth = $menu.width();  // width of menu 
  
    // Calculate fitCount on the total width this time
    fitCount = Math.floor((elemWidth / varWidth) * ctr) - 1;
    
    // Reset display and width on all list-items
    $menu.children().css({"display": "block", "width": "auto"});
  
    // Make a set of collected list-items based on fitCount
    $collectedSet = $menu.children(":gt(" + fitCount + ")");
  
    // Empty the more menu and add the collected items
    $("#submenu").empty().append($collectedSet.clone());  
  
    // Set display to none and width to 0 on collection,
    // because they are not visible anyway.
    $collectedSet.css({"display": "none", "width": "0"});
}
Run Code Online (Sandbox Code Playgroud)
* { box-sizing: border-box; margin: 0; padding: 0; }
div { position: relative; background-color: #ccc; height: 32px; overflow: visible; }
ul#menu, ol { height: 32px; max-width: 80%; overflow: hidden; }
ul#menu > li, ol > li { display: block; float: left; height: 32px; white-space: nowrap; padding: 4px 8px; }
ol { position: absolute; right: 0; top: 0; overflow: visible; }
ol > li { min-width: 120px; }
ol ul { position: absolute; top: 120%; right: 10%; }
ol li ul > li { list-style: none; background-color: #eee; border: 1px solid gray; padding: 4px 8px;}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <ul id="menu">
        <li>Option One</li><li>Option Two</li><li>Option Three</li>
        <li>Option Four</li><li>Option Five</li><li>Option Six</li>
    </ul>
    <ol><li>Collected<ul id="submenu"></ul></li></ol>
</div>
Run Code Online (Sandbox Code Playgroud)