Сложно поведение на Bootstrap Collapse

Как да внедря свиване на Bootstrap 4 върху йерархия от елементи (навигационни ленти в моя случай)

Имам следната йерархия на някои елементи за моята страница и искам да използвам поведението на свиване в това „дърво“.

Фигура 1

По-конкретно пожелавам следното поведение

(което вярвам, че има смисъл)

Където зеленото означава, че навигационната лента е показана, а червеното означава, че е свита

Фигура 2

Със сегашното състояние

и щракнете върху Опция B1

Фигура 3

това просто свива навигационната лента B1

В друг пример, когато щракнете върху опция A

Фигура 4

Това показва лента за навигация A

и свива всички наследници на опция B

(навигационна лента B и навигационна лента B1)

Фигура 5

Правилата могат да бъдат сведени до 3 прости правила:

1) При щракване върху елемент с активни деца (и евентуално други потомци) (и тук активни имам предвид показани), всички деца и потомци се свиват.

2) Когато щракнете върху елемент X, който няма активни деца, тогава покажете (директните) деца на X И свийте всички наследници на братята и сестрите на X.

3) всички наследници на основната навигация се зареждат свити

Можех да постигна желаното поведение с персонализиран javascript код и за съжаление трябваше да игнорирам някои желани функционалности, които вече са предоставени от приставката за свиване от bootstrap, и да ги внедря отново според нуждите си.

Отидете тук за 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="/bg#" 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="/bg#" 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="/bg#">Option A1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="/bg#">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="/bg#" 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="/bg#">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="/bg#">Option B1.1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="/bg#">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 и премахване на някои атрибути на данни от някои връзки, за да се избегнат конфликти между някои автоматични функции от плъгина с моя персонализиран код.


person gota    schedule 06.09.2017    source източник
comment
Не можете да очаквате персонализиран javascript в отговора, тъй като може да е, че текущата реализация на bootstrap 4 е погрешна. Освен това вие не сте показали никакъв опит, някой html код, който сте опитали, би бил добър.   -  person Deckerz    schedule 08.09.2017
comment
Трябва да покажете някои изследователски усилия или някакъв код, който сте опитвали.   -  person JohanSellberg    schedule 08.09.2017
comment
И двамата сте прави! Вече направих някои проучвания и измислих свой персонализиран код, който да работи. Търся по-принципен начин да направя това   -  person gota    schedule 08.09.2017
comment
Благодаря ви за отрицателните гласове! Винаги ме прави по-добър човек   -  person gota    schedule 08.09.2017
comment
Предлагам да използвате цигулка или да актуализирате въпроса си с отговора, който сте направили, който ще покаже усилията ви и с удоволствие ще премахна моето -1 до +1. Показва, че сте го пробвали с cusom, но търсите не. персонализиран javascript.   -  person JohanSellberg    schedule 08.09.2017
comment
Не вярвам, че има начин да направите това без персонализиран JavaScript. Вярвам обаче, че има лесен начин да направите това с помощта на API за свиване на Bootstrap (което все още смятам за най-добра практика.) Само се колебая да публикувам, тъй като не отговаря на очакванията за персонализиран javascript.   -  person inki    schedule 14.09.2017


Отговори (2)


Пример за работещ Bootply

Моят подход включва следните актуализации:


1. Включете липсващ атрибут към връзките си (<a>)

Добавете атрибута data-toggle="collapse" към връзките на менюто. Това ще ви даде очакваното поведение на Bootstrap за колапс. Пример:

<a id="togglenavA" class="nav-link" href="/bg#" 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 може да бъде опростен само до следния фрагмент:

$(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.

person inki    schedule 14.09.2017
comment
готино! Мисля, че имате ненужен код, по-специално $('#navA').on('show.bs.collapse', function(){ $('#navB').collapse('hide'); }); $('#navB').on('show.bs.collapse', function(){ $('#navA').collapse('hide'); }); Изглежда, че искате да приложите стила на акордеон, но той вече е там! Вижте това разклонение bootply.com/hUC5aXD5AF# Бихте ли заменили връзката към тази? - person gota; 15.09.2017
comment
Да, прав си. Остана от първия ми опит за това. Редактирах JS и връзката към работещия пример на Bootply. - person inki; 15.09.2017

Добре, намерих начин да направя това с персонализиран javascript код и игнориране на някои желани функционалности, предоставени от приставката за свиване от bootstrap, и повторното им прилагане според нуждите ми.

Ето опростената 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="/bg#" 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="/bg#" 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="/bg#">Option A1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="/bg#">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="/bg#" 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="/bg#">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="/bg#">Option B1.1</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="/bg#">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 и премахване на някои атрибути на данни от някои връзки, за да се избегнат конфликти между някои автоматични функции от pluguin с моя персонализиран код.

person gota    schedule 08.09.2017