Bootstrap 折叠复杂行为

Posted

技术标签:

【中文标题】Bootstrap 折叠复杂行为【英文标题】:Bootstrap Collapse complex behaviour 【发布时间】:2018-02-14 19:49:39 【问题描述】:

如何在元素层次结构上实现 Bootstrap 4 折叠(在我的例子中是导航栏)

我的页面的某些元素具有以下层次结构,我希望在此“树”中使用折叠行为。

特别希望以下行为

(我认为这是有道理的)

绿色表示导航栏已显示,红色表示已折叠

与当前状态

然后点击选项 B1

这只是折叠导航栏 B1

在另一个例子中点击选项 A

这显示了导航栏 A

并折叠选项 B 的所有后代

(导航栏 B 和导航栏 B1)

这些规则可以归结为 3 个简单的规则:

1) 当点击一个元素时,一些子元素(可能还有其他后代)处于活动状态(这里是活动的,我的意思是显示)所有子元素和后代都会崩溃。

2) 单击没有活动子元素的元素 X 时,显示 X 的(直接)子元素并折叠 X 的兄弟姐妹的所有后代。

3) 主导航的所有后代都被折叠加载

我可以使用自定义 javascript 代码获得所需的行为,不幸的是,我需要忽略引导程序中的折叠插件已经提供的一些所需功能,并根据我的需要重新实现它们。

去这里Bootply

这是简化的 html 部分

<nav id="main-nav" class="navbar navbar-expand-lg navbar-dark">
    <ul class="navbar-nav align-nav">
        <li class="nav-item">
            <a id="togglenavA" class="nav-link" href="#" data-target="#navA" aria-controls="navA" aria-expanded="false" aria-label="Toggle navigation">Option A</a>
        </li>
        <li class="nav-item">
            <a id="togglenavB" class="nav-link" href="#" data-target="#navB" aria-controls="navB" aria-expanded="false" aria-label="Toggle navigation">Option B</a>
        </li>
    </ul>
</nav>
<div id="navA" class="collapse">
    <nav id="NAVA" class="navbar navbar-expand-lg navbar-dark">
        <ul class="navbar-nav align-nav">
            <li class="nav-item">
                <a class="nav-link" href="#">Option A1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Option A2</a>
            </li>
        </ul>
    </nav>
</div>
<div id="navB" class="collapse">
    <nav id="NAVB" class="navbar navbar-expand-lg navbar-dark">
        <ul class="navbar-nav align-nav">
            <li class="nav-item">
                <a id="togglenavB1" class="nav-link" href="#" data-target="#navB1" aria-controls="navB1" aria-expanded="false" aria-label="Toggle navigation">Option B1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Option B2</a>
            </li>
        </ul>
    </nav>
</div>
<div id="navB1" class="collapse">
    <nav id="NAVB1" class="navbar navbar-expand-lg navbar-dark">
        <ul class="navbar-nav align-nav">
            <li class="nav-item">
                <a class="nav-link" href="#">Option B1.1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Option B1.2</a>
            </li>
        </ul>
    </nav>
</div>

这里是重新实现手风琴风格的 Javascript,但兄弟姐妹的孩子的额外折叠

$(document).ready(function() 
    $('#togglenavA').click(function() 
        $('#navB').collapse('hide')
        $('#navB1').collapse('hide')
        $('#navA').collapse('toggle')
        $('#navA').on('hidden.bs.collapse', function () 
            $('#togglenavA').attr("aria-expanded","false");
        ) // for screen readers purpose
        $('#navA').on('shown.bs.collapse', function () 
            $('#togglenavA').attr("aria-expanded","true");
        )
    );
    $('#togglenavB').click(function() 
        $('#navA').collapse('hide')
        $('#navB1').collapse('hide')
        $('#navB').collapse('toggle')
        $('#navB').on('hidden.bs.collapse', function () 
            $('#togglenavB').attr("aria-expanded","false");
        )
        $('#navB').on('shown.bs.collapse', function () 
            $('#togglenavB').attr("aria-expanded","true");
        )
    );
    $('#togglenavB1').click(function() 
        $('#navB1').collapse('toggle')
        $('#navB1').on('hidden.bs.collapse', function () 
            $('#togglenavB1').attr("aria-expanded","false");
        )
        $('#navB1').on('shown.bs.collapse', function () 
            $('#togglenavB1').attr("aria-expanded","true");
        )
    );
);

注意:尽管此解决方案解决了我的问题,但这样做的代价是忽略了 Bootstrap 已经实现的手风琴并从某些链接中删除了一些数据属性,以避免插件中的某些自动功能与我的自定义代码发生冲突.

【问题讨论】:

您不能期望答案中没有自定义 javascript,因为这可能是 bootstrap 4 当前的实现存在缺陷。您自己也没有尝试过,您尝试过的一些html代码会很好。 你需要展示一些研究成果或你尝试过的一些代码。 你们俩都是对的!我已经做了一些研究,并想出了我自己的定制代码来工作。我正在寻找一种更有原则的方式来做到这一点 我建议使用小提琴或用您所做的答案更新您的问题,这将显示您的努力,并且我很乐意将我的 -1 删除为 +1。表明您使用 cusom 尝试过但正在寻找非。自定义 javascript。 我不相信没有自定义 JavaScript 可以做到这一点。但是,我相信有一种使用 Bootstrap 的 Collapse API 的简单方法(我认为这仍然是最佳实践。)我只是犹豫发布,因为它不满足“没有自定义 javascript”的期望。 【参考方案1】:

Working Bootply example

我的方法涉及以下更新:


1。在您的链接中添加缺少的属性 (&lt;a&gt;)

data-toggle="collapse" 属性添加到菜单链接。这将为您提供开箱即用的预期 Bootstrap 折叠行为。示例:

<a id="togglenavA" class="nav-link" href="#" data-toggle="collapse" data-target="#navA" aria-controls="navA" aria-expanded="false" aria-label="Toggle navigation">Option A</a>

2。添加二级班级collapse-child

这允许我们定位这些子导航栏。示例:

<div id="navA" class="collapse collapse-child">

3。 JavaScript

然后可以将 JavaScript 简化为以下 sn-p:

$(document).ready(function() 
  var hideChildren = function() 
    $('div.collapse-child').collapse('hide');
  ;

  $('a.nav-link:not([aria-controls])').click(function(el)
    hideChildren();
  );

  $('#main-nav a').click(function()
    hideChildren();
  );
);

我不确定这是否满足您的“无自定义 Javascript”要求,但我认为这是使用最新版本的 Bootstrap4 实现此目标的“最佳实践”方式。

【讨论】:

酷!我认为您有不必要的代码,特别是 $('#navA').on('show.bs.collapse', function() $('#navB').collapse('hide'); ); $('#navB').on('show.bs.collapse', function() $('#navA').collapse('hide'); );看来您想实现手风琴风格,但它已经存在了!看到这个 fork bootply.com/hUC5aXD5AF# 你能替换这个链接吗? 是的,你是对的。这是我第一次尝试时遗留下来的。我编辑了 JS 和工作 Bootply 示例的链接。【参考方案2】:

好的,我找到了一种使用自定义 javascript 代码执行此操作的方法,并忽略了引导程序中折叠插件提供的一些所需功能,并根据我的需要重新实现它们。

这是简化的 HTML 部分

<nav id="main-nav" class="navbar navbar-expand-lg navbar-dark">
    <ul class="navbar-nav align-nav">
        <li class="nav-item">
            <a id="togglenavA" class="nav-link" href="#" data-target="#navA" aria-controls="navA" aria-expanded="false" aria-label="Toggle navigation">Option A</a>
        </li>
        <li class="nav-item">
            <a id="togglenavB" class="nav-link" href="#" data-target="#navB" aria-controls="navB" aria-expanded="false" aria-label="Toggle navigation">Option B</a>
        </li>
    </ul>
</nav>
<div id="navA" class="collapse">
    <nav id="NAVA" class="navbar navbar-expand-lg navbar-dark">
        <ul class="navbar-nav align-nav">
            <li class="nav-item">
                <a class="nav-link" href="#">Option A1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Option A2</a>
            </li>
        </ul>
    </nav>
</div>
<div id="navB" class="collapse">
    <nav id="NAVB" class="navbar navbar-expand-lg navbar-dark">
        <ul class="navbar-nav align-nav">
            <li class="nav-item">
                <a id="togglenavB1" class="nav-link" href="#" data-target="#navB1" aria-controls="navB1" aria-expanded="false" aria-label="Toggle navigation">Option B1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Option B2</a>
            </li>
        </ul>
    </nav>
</div>
<div id="navB1" class="collapse">
    <nav id="NAVB1" class="navbar navbar-expand-lg navbar-dark">
        <ul class="navbar-nav align-nav">
            <li class="nav-item">
                <a class="nav-link" href="#">Option B1.1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Option B1.2</a>
            </li>
        </ul>
    </nav>
</div>

这里是重新实现手风琴风格的 Javascript,但兄弟姐妹的孩子的额外折叠

$(document).ready(function() 
    $('#togglenavA').click(function() 
        $('#navB').collapse('hide')
        $('#navB1').collapse('hide')
        $('#navA').collapse('toggle')
        $('#navA').on('hidden.bs.collapse', function () 
            $('#togglenavA').attr("aria-expanded","false");
        ) // for screen readers purpose
        $('#navA').on('shown.bs.collapse', function () 
            $('#togglenavA').attr("aria-expanded","true");
        )
    );
    $('#togglenavB').click(function() 
        $('#navA').collapse('hide')
        $('#navB1').collapse('hide')
        $('#navB').collapse('toggle')
        $('#navB').on('hidden.bs.collapse', function () 
            $('#togglenavB').attr("aria-expanded","false");
        )
        $('#navB').on('shown.bs.collapse', function () 
            $('#togglenavB').attr("aria-expanded","true");
        )
    );
    $('#togglenavB1').click(function() 
        $('#navB1').collapse('toggle')
        $('#navB1').on('hidden.bs.collapse', function () 
            $('#togglenavB1').attr("aria-expanded","false");
        )
        $('#navB1').on('shown.bs.collapse', function () 
            $('#togglenavB1').attr("aria-expanded","true");
        )
    );
);

注意:尽管此解决方案解决了我的问题,但这样做的代价是忽略了 Bootstrap 已经实现的手风琴并从某些链接中删除了一些数据属性,以避免来自插件的某些自动功能与我的自定义代码发生冲突.

【讨论】:

以上是关于Bootstrap 折叠复杂行为的主要内容,如果未能解决你的问题,请参考以下文章

[Bootstrap]- Dropdown 与 Collapse 一起使用时的奇怪行为

Bootstrap 4嵌套折叠“数据父级”不起作用

Bootstrap 4导航栏不会在大屏幕上折叠

bootstrap - 网格系统 - 连续折叠/展开 1 个项目

Twitter Bootstrap 按钮单击以切换按钮上方的展开/折叠文本部分

Twitter Bootstrap 100% 高度手风琴“跳跃”