Сворачивающиеся панели Bootstrap перекрывают друг друга, когда я использую Masonry

У меня есть следующая страница:

    $(function () {
        var container = document.querySelector('#PanelContainer');
        var msnry = new Masonry(container, {
            itemSelector: '.selector-class',
            isAnimated: true,
            animationOptions: {
                duration: 750,
                easing: 'linear',
                queue: false
            }   
        });
        $(".spoiler-trigger").click(function () {
            $(this).parent().next().collapse('toggle');
        });
    })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>

<div class="container">
<div id="PanelContainer" class="row">
    <div class="col-md-6 selector-class">
        <div class="panel panel-primary card-0">
          <div class="panel-heading">
            <h3 class="panel-title">Title</h3>
        </div>
        <div class="panel-body">
          <div class="panel panel-default">
            <div class="panel-heading">
              <button type="button" class="btn btn-default btn-xs spoiler-trigger" data-toggle="collapse">Collapse</button>
            </div>
            <div class="panel-collapse collapse out">
              <div class="panel-body">Body</div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="col-md-6 selector-class">
        <div class="panel panel-primary card-0">
          <div class="panel-heading">
            <h3 class="panel-title">Title</h3>
        </div>
        <div class="panel-body">
          <div class="panel panel-default">
            <div class="panel-heading">
              <button type="button" class="btn btn-default btn-xs spoiler-trigger" data-toggle="collapse">Collapse</button>
            </div>
            <div class="panel-collapse collapse out">
              <div class="panel-body">Body</div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="col-md-6 selector-class">
        <div class="panel panel-primary card-0">
          <div class="panel-heading">
            <h3 class="panel-title">Title</h3>
        </div>
        <div class="panel-body">
          <div class="panel panel-default">
            <div class="panel-heading">
              <button type="button" class="btn btn-default btn-xs spoiler-trigger" data-toggle="collapse">Collapse</button>
            </div>
            <div class="panel-collapse collapse out">
              <div class="panel-body">Body</div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="col-md-6 selector-class">
        <div class="panel panel-primary card-0">
          <div class="panel-heading">
            <h3 class="panel-title">Title</h3>
        </div>
        <div class="panel-body">
          <div class="panel panel-default">
            <div class="panel-heading">
              <button type="button" class="btn btn-default btn-xs spoiler-trigger" data-toggle="collapse">Collapse</button>
            </div>
            <div class="panel-collapse collapse out">
              <div class="panel-body">Body</div>
            </div>
          </div>
        </div>
      </div>
    </div>
</div>
</div>

Все выглядит идеально, но когда пользователь пытается развернуть любую панель, она перекрывает другие. Как заставить Masonry пересчитывать и плавно обновлять расположение панелей?
P.S. Я новичок в JS.

ДОБАВЛЕНО
Я установил прослушиватели для событий Bootstrap:

$(document).on('hidden.bs.collapse', function () {
    msnry.layout();
});
$(document).on('shown.bs.collapse', function () {
    msnry.layout();
});

И мой макет начал обновлять себя, но если он имеет неправильное поведение для расширения. Теперь панель расширилась и после этого вызывает обновление макета, но мне нужно сделать это раньше.


person Шах    schedule 02.03.2017    source источник
comment
Я предполагаю, что вы не можете внести изменения до изменения размеров начальной загрузки (до анимации). Сначала он расширяется и меняет высоту, а уже после этого кладка знает, какие размеры ей использовать для разметки.   -  person laser    schedule 02.03.2017
comment
Что вы можете сделать, так это поместить каждый элемент начальной загрузки в какой-либо контейнер (так что в основном отделите col-md-6 от .selector-class. И в jquery перед ручным изменением размера контейнера запустите анимацию свертывания и в то же время запустите mnsry.layout() ... но это нужно проверить.   -  person laser    schedule 02.03.2017
comment
Благодарю вас! Попробую... Хотя, я не уверен, что кладка в этом случае сможет правильно поставить все блоки.   -  person Шах    schedule 02.03.2017


Ответы (1)


Надеюсь, это может помочь, у меня это работает, но только при использовании col-XX-[3/6/12] (из-за требования, чтобы width: был хорошим% возраста)

Это немного грязно, но функционально.

что стоит изменить/отметить:

чтобы обойти изменение макета при сворачивании/расширении, в JS есть setTimeout, который запускается при обновлении; в производстве или особенно для более медленных анимированных последовательностей развертывания/свертывания, я полагаю, что необходимо найти лучшее решение. но для анимации менее 100 мс, я думаю, вам это сойдет с рук.

В CSS, если вы использовали какой-либо столбец начальной загрузки больше, чем xs, вам нужно будет адаптировать css grid-item[-6,-12], чтобы он соответствовал правилам col для изменения ширины% с размером экрана.

В основном правила столбца начальной загрузки имеют приоритет, поэтому все не слишком разрушается.

[NB: мое событие .click привязано к текстовому заголовку на панели, а не к div заголовка панели]

$('.grid').masonry({
  itemSelector: '.grid-item',
  columnWidth: '.grid-sizer',
  percentPosition: true,

});

$('.panel-heading').click(function () {
	setTimeout(function() {
		$('.grid').masonry('layout');
	}, 300);
});
.grid-sizer, .grid-item {width: 25%;}

.grid-item--width-6 { width: 50%;}

.grid-item--width-12 { width: 100%;}

/* NOT required to work,it 
helps demo whats going on */
.panel-body {
	height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>

<link href="css/main.css" rel="stylesheet">



<div class="grid">
  <div class="grid-sizer"></div>

  <div class=" col-xs-12 grid-item grid-item--width-12">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h4 class="panel-title">
          <a data-toggle="collapse" href="#collapse0-m">panel 0</a>
        </h4>
      </div>
      <div id="collapse0-m" class="panel-collapse collapse">
        <div class="panel-body">Panel Body</div>
      </div>
    </div>
  </div>


  <div class=" col-xs-6 grid-item grid-item--width-6">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h4 class="panel-title">
          <a data-toggle="collapse" href="#collapse1-m">panel 1</a>
        </h4>
      </div>
      <div id="collapse1-m" class="panel-collapse collapse">
        <div class="panel-body">Panel Body</div>
      </div>
    </div>
  </div>

  <div class="col-xs-6 grid-item grid-item--width-6">
    <div class="panel panel-default">
     <div class="panel-heading">
       <h4 class="panel-title">
         <a data-toggle="collapse" href="#collapse2-m">panel 2</a>
       </h4>
     </div>
     <div id="collapse2-m" class="panel-collapse collapse">
       <div class="panel-body">Panel Body</div>
     </div>
   </div>
  </div>

  <div class="col-xs-3 grid-item">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h4 class="panel-title">
          <a data-toggle="collapse" href="#collapse3-m">panel 3</a>
        </h4>
      </div>
      <div id="collapse3-m" class="panel-collapse collapse">
        <div class="panel-body">Panel Body</div>
      </div>
    </div>
  </div>

  <div class="col-xs-3 grid-item">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h4 class="panel-title">
          <a data-toggle="collapse" href="#collapse4-m">panel 4</a>
        </h4>
      </div>
      <div id="collapse4-m" class="panel-collapse collapse">
        <div class="panel-body">Panel Body</div>
      </div>
    </div>
  </div>

  <div class="col-xs-6 grid-item grid-item--width-6">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h4 class="panel-title">
          <a data-toggle="collapse" href="#collapse5-m">panel 5</a>
        </h4>
      </div>
      <div id="collapse5-m" class="panel-collapse collapse">
        <div class="panel-body">Panel Body</div>
      </div>
    </div>
  </div>

</div>



    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->

    <script src="js/main.js"></script>

    <!-- Include all compiled plugins (below), or include individual files as needed -->

person penuts    schedule 24.05.2017
comment
Спасибо за решение! Хотя мы уже выпустили это приложение =) - person Шах; 25.05.2017