Некоторые проблемы с коллапсом Bootstrap + навигация по вкладкам

JsFiddle: http://jsfiddle.net/p5sZJ/10/

Баг воспроизводится только в IE 10 (хром, фаерфокс работают отлично). Ошибка не воспроизводится в IE 9, потому что он не поддерживает переходы css. Ошибка не воспроизводится в IE 11 и в IE 11, работающем в режиме IE 10. (см. мое последнее редактирование, эта информация неактуальна)

Действия по воспроизведению ошибки:

  1. Нажмите на вкладку «Вторая».
  2. Нажмите на "Заголовок" свернуть.
  3. Откройте внутренний коллапс, нажав на «Внутреннюю ссылку».
  4. Закройте внутренний коллапс, снова щелкнув «Внутреннюю ссылку».
  5. Нажмите на вкладку «Первая».
  6. Нажмите «Ссылка для открытия аккордеона».
  7. Попробуйте открыть-закрыть внутренний обвал и основной обвал.

Ожидаемый результат: створки прекрасно открываются и закрываются. Фактический результат: свертывание не работает.

HTML:

<ul id="mainTab" class="nav nav-tabs">
    <li><a href="#first" data-toggle="tab">First</a></li>
    <li><a href="#second" data-toggle="tab">Second</a></li>
</ul>

<div id="mainTabContent" class="tab-content" ng-app="myApp" ng-controller="MyCtrl">
    <div id="first" class="tab-pane">
        <a id="anchor" ng-click="navigate()">Link to open accordion</a>
    </div>

    <div id="second" class="tab-pane">
        <div id="second-accordion" class="accordion">
        <div class="accordion-group">
            <div class="accordion-heading">
                <a class="accordion-toggle" data-toggle="collapse" href="#second-body">
                    Heading
                </a>
            </div>
            <div id="second-body" class="accordion-body collapse">
                <table class="table">
                    <thead>
                        <tr>
                            <th>Table Head</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>
                                <a id="anchor-inner" href="#second-inner" data-toggle="collapse">
                                    Inner link
                                </a>
                            </td>
                        </tr>
                        <tr class="collapse-row">
                            <td>
                                <div id="second-inner" class="collapse">
                                    <div class="inner-description">
                                        Description
                                    </div>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

Js:

var module = angular.module('myApp', []);

module.controller('MyCtrl', function($scope){
    $scope.navigate = function(){
        $('#mainTab li:eq(1) a').tab('show');

        var inner = $('#second-inner');

        if (!$(inner).parents('.collapse').hasClass('in')) {
            $(inner).parents('.collapse').collapse('show');
        }
        if (!$(inner).hasClass('in')) {
            $(inner).collapse('show');
        }
    };  
});

$(document).ready(function(){
    var collapse = $('.collapse');

    collapse.on('hidden', function (event) {
        $(event.target).children().hide();
    });

    collapse.on('show', function (event) {
        $(event.target).children().show();
    });    
});

P.S. Похоже, ошибка воспроизводится только при использовании AngularJs. (см. мое последнее редактирование, эта информация неактуальна) Почему-то в IE 10 событие "transitionend" не вызывается, и поэтому свертывания застревают, но почему оно не возникает.

Изменить:

Баг воспроизводится без AngularJS и во всех браузерах. Я добавил комментарии к своему ответу. Вы можете воспроизвести ошибку, просто щелкнув вкладку (в которой есть свернутый элемент), а затем сразу же щелкнув заголовок сворачивания, чтобы развернуться. Попробуйте несколько раз в старом jsfiddle.


person hapass    schedule 16.01.2014    source источник


Ответы (2)


В моем случае сработало обертывание вызовов roll('show') в setTimeOut 0.

http://jsfiddle.net/p5sZJ/12/

var module = angular.module('myApp', []);

module.controller('MyCtrl', function($scope){
    $scope.navigate = function(){
        $('#mainTab li:eq(1) a').tab('show');

        var inner = $('#second-inner');

        setTimeOut(function(){
        if (!$(inner).parents('.collapse').hasClass('in')) {
            $(inner).parents('.collapse').collapse('show');
        }
        if (!$(inner).hasClass('in')) {
            $(inner).collapse('show');
        }}, 0);
    };  
});

$(document).ready(function(){
    var collapse = $('.collapse');

    collapse.on('hidden', function (event) {
        $(event.target).children().hide();
    });

    collapse.on('show', function (event) {
        $(event.target).children().show();
    });    
});

Изменить:

Наконец-то я обнаружил настоящий источник проблемы и почему вы должны установить тайм-аут для ее устранения. По-видимому, вы должны быть очень осторожны при отображении элементов коллапса и взаимодействии с ними сразу после этого, потому что событие transitionEnd может не сработать. Подробности можно найти здесь: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions . Так что вам лучше установить тайм-аут 20, а не ноль. Кроме того, если пользователь открывает вкладку с коллапсом и сразу же нажимает на коллапс, это может сломаться даже в хроме.

person hapass    schedule 11.02.2014

Попробуйте использовать bootstrap Ui http://angular-ui.github.io/bootstrap/ Его специальная библиотека для совместной работы начальной загрузки с angular.

person Łukasz Ł    schedule 12.02.2014
comment
да, это был один из возможных вариантов решения проблемы, но на проекте уже было написано слишком много кода, и потребовалось бы слишком много усилий, чтобы использовать bootstrap ui. хотя спасибо за ответ :) - person hapass; 12.02.2014