【问题标题】:build a downloadable content in 3 columns在 3 列中构建可下载的内容
【发布时间】:2016-07-11 23:31:08
【问题描述】:

我从 JSON 中获取响应,并希望将其粘贴到 3 列中。我正在使用引导类 col-md-4 和 angularjs 作为框架。我想连续排列 3 个元素,但是当内容太大时 - 它会分解并看起来像:

见下面plnkr (view in fullscreen)

【问题讨论】:

  • 可以用css3 flexbox代替float

标签: css angularjs twitter-bootstrap


【解决方案1】:

如果您只想将 3 列无限地放置在一行 @ 992 像素或更大 (col-md-4) 中,只需在该媒体查询中清除列的浮动即可。

@media (min-width: 992px) {
    .col-md-4:nth-child(3n+1) {
        clear: left;
    }
}

*不要将它直接应用于 col-md-4,因为它会全局应用于该类。

清除列浮动示例

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

app.controller('Ctrl', function($scope) {
  $scope.list = [{
    name: 'John1',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John2',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John3',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John4',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John5',
    text: ['asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas']
  }, {
    name: 'John6',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John7',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John8',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs', 'asdfasdfasdfasdfasfsadfasdfsdfs', 'asdfasdfasdfasdfasfsadfasdfsdfs', 'asdfasdfasdfasdfasfsadfasdfsdfs', 'asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John9',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John10',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }]
})
.grid-item-inner {
  background: #333;
  color: white;
  border: 1px solid red;
  padding: 0px 10px 10px;
  margin: 10px 0;
}
@media (min-width: 991px) {
  .grid-item:nth-child(3n+1) {
    clear: left;
  }
}
<html ng-app="App">
<head>
  <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body ng-controller="Ctrl">
  <div class="container">
    <div class="row">
      <div class="col-md-4 grid-item" ng-repeat="item in list">
        <div class="grid-item-inner">
          <h3>{{item.name}}</h3>
          <ul class="list-unstyled">
            <li ng-repeat="thing in item.text track by $index">{{thing}}</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.js"></script>
</body>
</html>

或者,如果您尝试将每一列直接放在另一列下方(砌体布局),一种方法是使用 MasonryJS。见Angular-Masonry

用于砌体示例的 AngularJS 指令

'use strict';

angular.module('ngMasonry', [])
  .controller('masonryController', function() {
    var vm = this;

    vm.config = {};
    vm.container = undefined;
    vm.ready = ready;
    vm.initialize = initialize;
    vm.reLayout = reLayout;

    function ready() {
      return !!vm.config && !!vm.config.masonryContainer;
    }

    function initialize() {
      var defaultOpts = {
          itemSelector: vm.config.masonryItem
        },
        opts = !vm.config.masonryOption ? defaultOpts : angular.extend(defaultOpts, vm.config.masonryOption);

      vm.container = new Masonry(vm.config.masonryContainer, opts);

      if (typeof imagesLoaded !== 'undefined') {
        new imagesLoaded(vm.config.masonryContainer, function() {
          vm.reLayout();
        });
      }
    }

    function reLayout() {
      vm.container.layout();
    }
  })
  .directive('masonry', function() {
    var directive = {
      restrict: 'A',
      controller: 'masonryController',
      compile: compile
    };

    return directive;

    function compile(element, attributes) {
      var flag = false,
        child = angular.element(document.querySelectorAll('[' + attributes.$attr.masonry + '] [data-masonry-item], [' + attributes.$attr.masonry + '] [masonry-item]'));

      angular.forEach(child, function(obj) {
        obj = angular.element(obj);
        if (obj.attr('ng-repeat') !== undefined || obj.attr('data-ng-repeat') !== undefined) {
          flag = true;
          obj.attr('data-masonry-after-render', '');
        }
      });
      return {
        pre: function(scope, element, attributes, controller) {
          controller.config.masonryContainer = '[' + attributes.$attr.masonry + ']';
          controller.config.masonryOptions = JSON.parse(attributes.masonryOptions || '{}');
        },
        post: function(scope, element, attributes, controller) {
          if (!flag) {
            controller.initialize();
          }
        }
      };
    }
  })
  .directive('masonryItem', function() {
    var directive = {
      restrict: 'A',
      require: '^masonry',
      priority: 1,
      compile: compile
    };

    return directive;

    function compile() {
      return {
        pre: function(scope, element, attributes, controller) {
          if (controller.config.masonryItem === undefined) {
            controller.config.masonryItem = '[' + attributes.$attr.masonryItem + ']';
          }
        }
      };
    }
  })
  .directive('masonryAfterRender', function($timeout) {
    'ngInject';
    var directive = {
      restrict: 'A',
      require: '^masonry',
      priority: 0,
      link: link
    };

    return directive;

    function link(scope, element, attr, controller) {
      if (scope.$last) {
        var timeout = null;
        timeout = $timeout(function() {
          controller.initialize();
          $timeout.cancel(timeout);
        });
      }
    }
  });

//Your Code Starts Here

var app = angular.module('App', ['ngMasonry']);

app.controller('Ctrl', function($scope) {
  $scope.list = [{
    name: 'John1',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John2',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John3',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John4',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John5',
    text: ['asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas', 'asdfasdfas']
  }, {
    name: 'John6',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John7',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John8',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs', 'asdfasdfasdfasdfasfsadfasdfsdfs', 'asdfasdfasdfasdfasfsadfasdfsdfs', 'asdfasdfasdfasdfasfsadfasdfsdfs', 'asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John9',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }, {
    name: 'John10',
    text: ['asdfasdfasdfasdfasfsadfasdfsdfs']
  }]
})
.grid-item-inner {
  background: #333;
  color: white;
  border: 1px solid red;
  padding: 0px 10px 10px;
  margin: 10px 0;
}
@media (max-width: 992px) {
  .grid-item {
    width: 100%;
  }
}
<html data-ng-app="App">
<head>
  <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body ng-controller="Ctrl">
  <div class="container">
    <div class="row" data-masonry>
      <div class="col-md-4 grid-item" data-masonry-item data-ng-repeat="item in list">
        <div class="grid-item-inner">
          <h3>{{item.name}}</h3>
          <ul class="list-unstyled">
            <li ng-repeat="thing in item.text track by $index">{{thing}}</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/masonry/3.3.2/masonry.pkgd.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/3.2.0/imagesloaded.pkgd.min.js"></script>
</body>
</html>

**一般来说,Bootstrap Grid 应该使用这种模式:

container or container-fluid
  row
    col-*-*

您当前有行后跟容器。见Grid

【讨论】:

    【解决方案2】:

    问题是 bootstrap 3 使用浮动,因此为了使列在不同高度时保持正确对齐,您需要在其中放置一个虚拟 clearfix。

    Bootstrap Clearfix

    你可以做的一个可选的事情是将每一行包装在一个“行”中,哈哈。因此,在您的情况下,每三列都应包含在自己的 div 中,并带有一类行。

    这两种解决方案都会在 ng-repeat 中产生问题,因为您必须按所需的列数对数据进行分组,然后再次嵌套重复。有人可能有更好的解决方案。

    就像上面建议的 charlietfl 一样,最不令人沮丧的事情是使用 flexbox。您可以自己编写 css 或切换到 bootsrap 4,但问题是 IE 中的支持不是最好的。

    您也可以重写列 css 以使用内联块而不是浮点数,但此时使用 bootstrap =P 有什么意义

    .col-4 {
      width: 32%;
      display:inline-block;
      margin-bottom: 10px;
      vertical-align: top;
    }
    
    .col-4:nth-of-type(3n-1) {
      margin-left: 2%;
      margin-right: 2%;
    }
    

    Like so

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-12
      • 1970-01-01
      • 2018-01-15
      • 2020-05-31
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多