砌体和动态选项卡

Masonry and dynamic tabs

我有这个包含动态选项卡的页面。选项卡内的内容根据用户选择的选项卡而变化。我想让那些内容用 Masonry 布局,这样它看起来不错。

这是问题所在:当用户切换选项卡时,内容会折叠。像这样:

如果用户使用 window 大小,它会正确响应并布局。像这样:

现在我很确定我知道问题出在哪里了。我在 HTML 而不是 jquery 上使用砌体: <div class="row" data-masonry='{ "columnWidth": ".news-box", "itemSelector": ".news-box" }'>

所以我认为问题在于,如果未加载内容(在本例中为图像),HTML 上的砌体效果不佳。我四处寻找解决此问题的 JQuery 方法,但我的问题是由于某种原因我无法使 JQuery 工作。这个网站在 ASP.NET 上,我无法在 JQuery 上进行砌筑,这就是为什么我坚持使用 HTML。

这是我用 JQuery:

尝试过的方法,但没有成功
<script>
    $('.row').masonry({
        itemSelector: '.news-box',
        columnWidth: '.news-box'
    });
</script>

我知道那段代码不会等待图像加载。我的意思是我没有得到任何结果,甚至是错误的代码。

有什么方法可以解决 HTML 上的问题吗?让它在用户切换选项卡时内容完美布局?

编辑:我用 vanilla JS 得到了这个

var msnry = new Masonry('.row', {
    columnWidth: '.news-box',
    itemSelector: '.news-box'
});

也许我可以在这里得到一个事件处理程序?提示?

复制问题的示例代码

<!--TABS-->
<ul class="nav nav-tabs">
    <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
    <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
</ul>

<!--TAB CONTENT-->
<div class="tab-content">
    <div id="home" class="tab-pane fade in active">
        <!--DUMMY CONTENT FOR MAIN TAB-->
        <div class="row">
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title title title title title title title title title title title title title title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title title title title title title title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title title title title title title title title title title title title title title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title title title title title title title</h4>
            </div>
        </div>
    </div>
    <div id="menu1" class="tab-pane fade">
        <!--DUMMY CONTENT FOR SECONDARY TAB-->
        <div class="row">
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title title title title title title title title title title title title title title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title title title title title title title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title title title title title title title title title title title title title title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title</h4>
            </div>
            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
                <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
                <h4>title title title title title title title</h4>
            </div>
        </div>
    </div>
</div>

实际解决方案,基于您提供的代码:

var updateMasonry = function(){
  $('.tab-pane.active').masonry({
    itemSelector: '.well',
  })
}

$('a[data-toggle="tab"]').on('shown.bs.tab', updateMasonry);
$(window).on('resize load', updateMasonry)

var updateMasonry = function(){
  $('.tab-pane.active').masonry({
    itemSelector: '.well',
  })
}

$('a[data-toggle="tab"]').on('shown.bs.tab', updateMasonry);
$(window).on('resize load', updateMasonry)
/* you don't need this css */
@media (min-width: 700px) {
.container {margin-top: 80px;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/4.2.0/masonry.pkgd.min.js"></script>

<div class="container">
  <ul class="nav nav-tabs">
    <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
    <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
  </ul>

  <!--TAB CONTENT-->
  <div class="tab-content">
    <div id="home" class="tab-pane fade in active">
      <!--DUMMY CONTENT FOR MAIN TAB-->
      <div class="row">
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title title title title title title title title title title title title title title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title title title title title title title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title title title title title title title title title title title title title title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title title title title title title title</h4>
        </div>
      </div>
    </div>
    <div id="menu1" class="tab-pane fade">
      <!--DUMMY CONTENT FOR SECONDARY TAB-->
      <div class="row">
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title title title title title title title title title title title title title title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title title title title title title title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title title title title title title title title title title title title title title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title</h4>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 well well-sm">
          <img src="https://www.bypeople.com/wp-content/uploads/2016/07/css-stack-overflow-animated-logo.jpg" class="img-responsive" />
          <h4>title title title title title title title</h4>
        </div>
      </div>
    </div>
  </div>
</div>
<!--TABS-->


初始答案,展开...

您发布的<script>标签,满足后会运行。这意味着它将在以下时间执行:

  • 您的DOM对象还没有完全构建
  • 您的图片尚未加载(因为 DOM 构建比加载图片快得多)。

这就是为什么您需要在 window.load 事件上推送代码的执行,该事件发生在所有资产完成加载时:

window.onload = function() {
  var msnry = new Masonry('.row', {
    columnWidth: '.news-box',
    itemSelector: '.news-box'
  });
};

此外,我不完全确定将选择器传递给 columnWidth 参数是否有效。我认为它只能采用类似宽度的值(您可以使用 25% 来避免像素)。我的猜测是它目前被忽略了。它也没有多大意义,因为你给它 width 你正在调整大小的元素...


更多详情
从评论中可以看出,您正在尝试将 .masonry() 应用于放置在非活动选项卡中的内容。在大多数选项卡机制中,这意味着选项卡容器具有 display:none,这使得它不会被渲染并且其 width 将 return 0。因为 masonry() 使用容器的宽度来计算列,并放置项目,它确实有效,但所有列的宽度均为 0。这就是您可能想要做的。

步骤 1. 将您的 masonry init 方法放在一个函数中,这样您就可以在需要时调用它:

 var massonryInit = function() {
    var msnry  = new Masonry('.row', {
    columnWidth: '.news-box',
    itemSelector: '.news-box'
 });

第 2 步。 在选项卡显示后,查看您正在使用的任何选项卡的文档以获取回调方法 运行 选项卡内容。如果它们是 Bootstrap 选项卡,我们会谈论 shown.bs.tab 事件,但我知道您没有使用 Bootstrap,因为您没有使用 jQuery

在该方法中,您需要调用新声明的 massonryInit() 函数:

var yourTab = document.querySelector('yourTabSelectorHere');
yourTab.addEventListener("yourTabWasRenderedEvent", masonryInit);

请注意,上述方法仅适用于 return 由 yourTabselectorHere 编辑的单个特定选项卡。如果该选择器匹配多个元素,则事件将仅添加到第一个匹配项。要将它添加到所有,你需要 .querySelectorAll() 而不是 .querySelector() 并且你需要 运行 a javascript for 在该集合上并将事件添加到每个。

默认情况下,JavaScript 非常冗长。这就是 jQuery 如此受欢迎的原因。它将常用方法和任务的编写减少到更短的语法。以上所有,使用 jQuery 将是:

var masonryInit = function(){
  $('.row').masonry({
    itemSelector: '.news-box',
  });
}
$('yourTabSelectorHere').on('yourTabWasRenderedEvent', masonryInit);

... 它适用于多个选项卡。不需要 for 循环。它将由 jQuery.

在内部应用

除了上面的精彩解释外,这篇文章也非常值得一读: https://www.sitepoint.com/bootstrap-tabs-play-nice-with-masonry/

我找到的最好的简单解决方案是 销毁并初始化:

演示(Tabby.js 和砌体):https://codepen.io/ezra_siton/pen/KOLdBO?editors=1111

Removes the Masonry functionality completely. destroy will return the element back to its pre-initialized state.

  $grid.masonry("destroy");
  $grid.masonry(masonryOptions);

流程(将此与您的标签代码一起使用):**单击 tabX 显示 contectX - 销毁 gridX 而不是重新加载 gridX - **像魔法一样工作,没有任何复杂的技巧(比如超时或调整大小):)

思路来源于官方文档(Toggle Masonry):

Masonry - destroy

为什么不使用 "layout"(重新加载)?

因为这个想法只有在您更改网格(Append/prepended 项、更改元素大小等)时才有效。

  // trigger layout after item size changes
  $grid.masonry('layout');

示例(切换class并更新布局): https://masonry.desandro.com/methods.html#layout-masonry