【问题标题】:Bootstrap nav interactive tablist left and rightBootstrap nav 交互式 tablist 左右
【发布时间】:2019-11-13 20:17:56
【问题描述】:

我希望有两个左对齐(“第一”和“第二”)和一个右对齐(“更多”)的交互式导航。目前,我可以毫无问题地在“第一”和“第二”之间切换。但是,如果我选择“更多”,我可以切换回“第一”或“第二”,但不能再切换回“更多”,因为它无法被停用。

有没有办法将两个选项卡列表视为一个,或者只使用一个选项卡列表,左侧两个选项卡,右侧一个选项卡?

Js fiddle link

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <title>Site</title>
</head>

<body>
    <div class="container">
        <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
            <a class="navbar-brand" href="#">Site</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup"
                aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
                <div class="navbar-nav nav" id="nav-tab" role="tablist">
                    <a class="nav-item nav-link active" id="nav-first-tab" data-toggle="tab" href="#nav-first"
                        role="tab" aria-controls="nav-first" aria-selected="true">First</a>
                    <a class="nav-item nav-link" id="nav-second-tab" data-toggle="tab" href="#nav-second" role="tab"
                        aria-controls="nav-second" aria-selected="false">Second</a>
                </div>

                <div class="navbar-nav nav ml-auto" id="nav-tab-right" role="tablist">
                    <a class="nav-item nav-link" id="nav-more-tab" data-toggle="tab" href="#nav-more" role="tab"
                        aria-controls="nav-more" aria-selected="false">More</a>
                </div>
            </div>
        </nav>

        <div class="tab-content" id="nav-tabContent">
            <!--First tab-->
            <div class="tab-pane show active" id="nav-first" role="tabpanel" aria-labelledby="nav-first-tab">
                <p>First!</p>
            </div>

            <!--Second tab-->
            <div class="tab-pane" id="nav-second" role="tabpanel" aria-labelledby="nav-second-tab">
                <p>Second!</p>
            </div>

            <!--More tab-->
            <div class="tab-pane" id="nav-more" role="tabpanel" aria-labelledby="nav-more-tab">
                <p>More!</p>
            </div>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
        integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous">
    </script>
</body>

</html>

【问题讨论】:

    标签: html css twitter-bootstrap bootstrap-4


    【解决方案1】:

    Bootstrap 默认 JavaScript 并不完全是 “魔术”,尽管有时感觉是这样。为了使其工作,必须做出某些假设。其中之一是您尊重提供的标记。

    你没有。在您的情况下,您不是仅从一个父 role="tablist" 容器控制 tablist,而是从两个父容器控制。所以你需要自己取消选择:

    $(function() {
      $('#navbarNavAltMarkup').on('click', '[role="tab"]', function(e) {
        $('[role="tab"].active', $(this).closest('.navbar-collapse')).each((i, el) => {
          $(el).removeClass('active show');
          $(el).attr('aria-selected', 'false');
        })
      })
    });
    

    看看它的工作原理:

    $(function() {
      $('#navbarNavAltMarkup').on('click', '[role="tab"]', function(e) {
        $('[role="tab"].active', $(this).closest('.navbar-collapse')).each((i, el) => {
          $(el).removeClass('active show');
          $(el).attr('aria-selected', 'false');
        })
      })
    });
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    
    <div class="container">
      <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="#">Site</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
        <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
          <div class="navbar-nav nav" id="nav-tab" role="tablist">
            <a class="nav-item nav-link active" id="nav-first-tab" data-toggle="tab" href="#nav-first" role="tab" aria-controls="nav-first" aria-selected="true">First</a>
            <a class="nav-item nav-link" id="nav-second-tab" data-toggle="tab" href="#nav-second" role="tab" aria-controls="nav-second" aria-selected="false">Second</a>
          </div>
    
          <div class="navbar-nav nav ml-auto" id="nav-tab-right" role="tablist">
            <a class="nav-item nav-link" id="nav-more-tab" data-toggle="tab" href="#nav-more" role="tab" aria-controls="nav-more" aria-selected="false">More</a>
          </div>
        </div>
      </nav>
    
      <div class="tab-content" id="nav-tabContent">
        <!--First tab-->
        <div class="tab-pane show active" id="nav-first" role="tabpanel" aria-labelledby="nav-first-tab">
          <p>First!</p>
        </div>
    
        <!--Second tab-->
        <div class="tab-pane" id="nav-second" role="tabpanel" aria-labelledby="nav-second-tab">
          <p>Second!</p>
        </div>
    
        <!--More tab-->
        <div class="tab-pane" id="nav-more" role="tabpanel" aria-labelledby="nav-more-tab">
          <p>More!</p>
        </div>
      </div>
    </div>

    另一种可能的解决方案是将所有选项卡控件保留在同一个 tablist 父级中,并根据需要使用自定义 CSS 来定位它们:

    @media(min-width: 992px) {
      #navbarNavAltMarkup .navbar-nav:first-child{
        flex-grow: 1;
      }
      #navbarNavAltMarkup .nav-item:last-child{
        margin-left: auto;
      }
    }
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <a class="navbar-brand" href="#">Site</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
      <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
        <div class="navbar-nav nav" id="nav-tab" role="tablist">
          <a class="nav-item nav-link active" id="nav-first-tab" data-toggle="tab" href="#nav-first" role="tab" aria-controls="nav-first" aria-selected="true">First</a>
          <a class="nav-item nav-link" id="nav-second-tab" data-toggle="tab" href="#nav-second" role="tab" aria-controls="nav-second" aria-selected="false">Second</a>
          <a class="nav-item nav-link" id="nav-more-tab" data-toggle="tab" href="#nav-more" role="tab" aria-controls="nav-more" aria-selected="false">More</a>
        </div>
      </div>
    </nav>

    为了彻底,我承认我期待 Bootstrap 4 更智能。我第一次尝试解决这个问题是简单地从每个 .nav 中删除 role="tablist" 并将其放在共同的父级上。
    它应该可以工作的!

    但是如果我们查看BS's source code,我们会看到他们使用NAV_LIST_GROUP: '.nav, .list-group', 作为列表选择器,而不是[role="tablist"],我很难理解为什么。

    恕我直言,应该使用 role,因为它已经为屏幕阅读器提供了完全相同的“角色”(它声明:在我的标记中的某处,您会找到一个列表选项卡控件,每个都标记为role="tab")。他们(Bootstrap 团队)可能担心新手编码人员会删除/忽略role 属性,并且选项卡将停止工作。好吧,当/如果您删除 role 属性时,它们不应该工作。一些用户依靠这些属性来更快地阅读/查找相关内容。

    【讨论】:

      【解决方案2】:

      我发现一个可能的快速解决方案是添加以下 javascript 代码,手动设置正确的类和属性,覆盖默认实现

      $('a[data-toggle="tab"]').on('show.bs.tab', function () {
          $('#nav-tab').children().removeClass('active');
          $('#nav-tab').children().removeClass('show');
          $('#nav-tab').children().attr('aria-selected', 'false');
          $('#nav-tab-right').children().removeClass('active');
          $('#nav-tab-right').children().removeClass('show');
          $('#nav-tab-right').children().attr('aria-selected', 'false');
      });

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-16
        • 2016-01-10
        • 2014-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-26
        相关资源
        最近更新 更多