在响应式导航中添加更多用于列表的按钮 [英] adding more button for list in responsive navigation

查看:70
本文介绍了在响应式导航中添加更多用于列表的按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个导航,可以说12个项目,而当分辨率变小时,项目会降到新行中.我需要确保当某个项目不再适合导航时,应在导航栏的右侧放置一个更多"下拉按钮.并放入下拉菜单中不适合的项目. 如果您不了解我,则下面是图片.

但是问题是导航项的宽度并不总是相同,因为导航项是从REST API生成的.

我试图制作jQuery脚本来计算项目宽度并将其添加到导航中. 这是我创建的脚本,我很着急,所以真的很糟糕.

我需要提供有关如何正确计算项目和导航宽度以及计算何时添加项目到导航或从导航中删除项目的帮助.

如果您不了解它,这里是图片: 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);
            }


        }
    }

  

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

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

解决方案

这个问题太旧了,但是我也想发表我的答案.也许这是更干净,更轻松的方法.我创建了一支笔: https://codepen.io/sergi95/pen/bmNoML

<div id="mainMenu" class="main-menu">
<ul id="autoNav" class="main-nav">
  <li>
    <a href="#">home</a>
  </li>
  <li>
    <a href="#">about us</a>
  </li>
  <li>
    <a href="#">portfolio</a>
  </li>
  <li>
    <a href="#">team</a>
  </li>
  <li>
    <a href="#">blog</a>
  </li>
  <li>
    <a href="#">contact</a>
  </li>
  <li id="autoNavMore" class="auto-nav-more">
    <a href="#" class="more-btn">more</a>
    <ul id="autoNavMoreList" class="auto-nav-more-list">
      <li>
        <a href="#">policy</a>
      </li>
    </ul>
  </li>
</ul>

const $mainMenu = $("#mainMenu");
    const $autoNav = $("#autoNav");
    const $autoNavMore = $("#autoNavMore");
    const $autoNavMoreList = $("#autoNavMoreList");
    autoNavMore = () => {
        let childNumber = 2;

        if($(window).width() >= 320) {
            // GET MENU AND NAV WIDTH
            const $menuWidth = $mainMenu.width();
            const $autoNavWidth = $autoNav.width();
            if($autoNavWidth > $menuWidth) {
                // CODE FIRES WHEN WINDOW SIZE GOES DOWN
                $autoNav.children(`li:nth-last-child(${childNumber})`).prependTo($autoNavMoreList);
                autoNavMore();
            } else {
                // CODE FIRES WHEN WINDOW SIZE GOES UP
                const $autoNavMoreFirst = $autoNavMoreList.children('li:first-child').width();
                // CHECK IF ITEM HAS ENOUGH SPACE TO PLACE IN MENU
                if(($autoNavWidth + $autoNavMoreFirst) < $menuWidth) {
                    $autoNavMoreList.children('li:first-child').insertBefore($autoNavMore);
                }
            }
            if($autoNavMoreList.children().length > 0) {
                $autoNavMore.show();
                childNumber = 2;
            } else {
                $autoNavMore.hide();
                childNumber = 1;
            }
        }
    }
    // INIT 
    autoNavMore();
    $(window).resize(autoNavMore);


.main-menu {
        max-width: 800px;
    }
    .main-nav {
        display: inline-flex;
        padding: 0;
        list-style: none;
    }
    .main-nav li a {
        padding: 10px;
        text-transform: capitalize;
        white-space: nowrap;
        font-size: 30px;
        font-family: sans-serif;
        text-decoration: none;
    }
    .more-btn {
        color: red;
    }
    .auto-nav-more {
        position: relative;
    }
    .auto-nav-more-list {
        position: absolute;
        right: 0;
        opacity: 0;
        visibility: hidden;
        transition: 0.2s;
        text-align: right;
        padding: 0;
        list-style: none;
        background: grey;
        border-radius: 4px;
    }
    .auto-nav-more:hover .auto-nav-more-list {
        opacity: 1;
        visibility: visible;
    }

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);
            }


        }
    }

 

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

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

解决方案

This question is too old, but i want to post my answer too. Maybe this is more cleaner and easier way. I have created a pen: https://codepen.io/sergi95/pen/bmNoML

<div id="mainMenu" class="main-menu">
<ul id="autoNav" class="main-nav">
  <li>
    <a href="#">home</a>
  </li>
  <li>
    <a href="#">about us</a>
  </li>
  <li>
    <a href="#">portfolio</a>
  </li>
  <li>
    <a href="#">team</a>
  </li>
  <li>
    <a href="#">blog</a>
  </li>
  <li>
    <a href="#">contact</a>
  </li>
  <li id="autoNavMore" class="auto-nav-more">
    <a href="#" class="more-btn">more</a>
    <ul id="autoNavMoreList" class="auto-nav-more-list">
      <li>
        <a href="#">policy</a>
      </li>
    </ul>
  </li>
</ul>

const $mainMenu = $("#mainMenu");
    const $autoNav = $("#autoNav");
    const $autoNavMore = $("#autoNavMore");
    const $autoNavMoreList = $("#autoNavMoreList");
    autoNavMore = () => {
        let childNumber = 2;

        if($(window).width() >= 320) {
            // GET MENU AND NAV WIDTH
            const $menuWidth = $mainMenu.width();
            const $autoNavWidth = $autoNav.width();
            if($autoNavWidth > $menuWidth) {
                // CODE FIRES WHEN WINDOW SIZE GOES DOWN
                $autoNav.children(`li:nth-last-child(${childNumber})`).prependTo($autoNavMoreList);
                autoNavMore();
            } else {
                // CODE FIRES WHEN WINDOW SIZE GOES UP
                const $autoNavMoreFirst = $autoNavMoreList.children('li:first-child').width();
                // CHECK IF ITEM HAS ENOUGH SPACE TO PLACE IN MENU
                if(($autoNavWidth + $autoNavMoreFirst) < $menuWidth) {
                    $autoNavMoreList.children('li:first-child').insertBefore($autoNavMore);
                }
            }
            if($autoNavMoreList.children().length > 0) {
                $autoNavMore.show();
                childNumber = 2;
            } else {
                $autoNavMore.hide();
                childNumber = 1;
            }
        }
    }
    // INIT 
    autoNavMore();
    $(window).resize(autoNavMore);


.main-menu {
        max-width: 800px;
    }
    .main-nav {
        display: inline-flex;
        padding: 0;
        list-style: none;
    }
    .main-nav li a {
        padding: 10px;
        text-transform: capitalize;
        white-space: nowrap;
        font-size: 30px;
        font-family: sans-serif;
        text-decoration: none;
    }
    .more-btn {
        color: red;
    }
    .auto-nav-more {
        position: relative;
    }
    .auto-nav-more-list {
        position: absolute;
        right: 0;
        opacity: 0;
        visibility: hidden;
        transition: 0.2s;
        text-align: right;
        padding: 0;
        list-style: none;
        background: grey;
        border-radius: 4px;
    }
    .auto-nav-more:hover .auto-nav-more-list {
        opacity: 1;
        visibility: visible;
    }

这篇关于在响应式导航中添加更多用于列表的按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆