【问题标题】:Bootstrap carousel with multiple items per slide and AngularJS引导轮播,每张幻灯片和 AngularJS 有多个项目
【发布时间】:2026-02-22 01:50:02
【问题描述】:

我正在使用 Bootstrap 在我的网站上显示轮播,并在 this example 之后的每张幻灯片中显示多个项目。使用静态图像效果很好,我对结果非常满意(this jsFiddle 上的示例,确保显示框架足够大以避免由于 boostrap 的媒体查询而产生的奇怪效果,我会处理稍后)。

但是现在,我想从一个变量中定义轮播的内容,并使用 ng-repeat 将其与 AngularJS 绑定。那就是出现问题的地方。数据已正确绑定,但仅显示被视为“活动”项目的图像。我知道这是有道理的,但它与静态定义的图像不同。请参阅this jsFiddle 以查看我的错误。

到目前为止我尝试了什么:

  • 显示所有项目并设置溢出:隐藏
  • 将项目大小更改为 33% 并显示所有内容,而不是使用 col-md-4 类

HTML

<div class="carousel-started-themes" style="height:150px; width:700px;">
  <div class="carousel slide" id="myCarousel">
    <div class="carousel-inner">
      <div class="item" ng-class="{active:!$index}" ng-repeat="img in image">
        <div class="col-md-4"><a href="#"><img ng-src="{{img}}" class="img-responsive"></a>
        </div>
      </div>
    </div>
    <a class="left carousel-control" href="#myCarousel" data-slide="prev" style="z-index:10000;"><i class="glyphicon glyphicon-chevron-left"></i></a>
    <a class="right carousel-control" href="#myCarousel" data-slide="next" style="z-index:10000;"><i class="glyphicon glyphicon-chevron-right"></i></a>
  </div>
</div>

JS

function MyCtrl($scope) {
  $scope.image =["https://wallpaperscraft.com/image/minimalism_sky_clouds_sun_mountains_lake_landscape_95458_1600x900.jpg", "https://wallpaperscraft.com/image/clouds_milky_way_eclipse_light_68883_1600x900.jpg", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSl5bsNT-Qtm0tfbydXFMuFCG27Kug6D5Z3hrgitIQqQq22Da95Ig", "https://wallpaper.wiki/wp-content/uploads/2017/05/Photos-1600x900-Wallpapers-HD.jpg", "https://wallpaperscraft.com/image/torzhok_tver_region_evening_sunset_river_reflection_autumn_russia_58028_1600x900.jpg", "https://wallpaper.wiki/wp-content/uploads/2017/04/wallpaper.wiki-1600x900-HD-Image-PIC-WPD0014727.jpg"];
}

$('#myCarousel').carousel({
  interval: false
});

$('.carousel .item').each(function() {
  var next = $(this).next();
  if (!next.length) {
    next = $(this).siblings(':first');
  }
  next.children(':first-child').clone().appendTo($(this));

  if (next.next().length > 0) {
    next.next().children(':first-child').clone().appendTo($(this));
  } else {
    $(this).siblings(':first').children(':first-child').clone().appendTo($(this));
  }
});

【问题讨论】:

    标签: javascript css angularjs twitter-bootstrap carousel


    【解决方案1】:

    为什么需要显示/隐藏?也许你可以只使用溢出:隐藏;并且只需使用 jquery 在没有滚动条的情况下左右滚动。这样一来,就永远不会有隐藏条件。

    【讨论】:

    • 我不确定我理解你的意思,因为我不“显示或隐藏”任何东西,项目的活动状态是 Bootstrap 轮播的原生状态。我尝试手动显示所有内容并溢出:隐藏;但不幸的是,行为大致相同。
    【解决方案2】:

    我找到了解决办法。

    问题在于 jQuery 执行速度太快,没有等到 ng-repeat 完成后才绑定数据并添加元素以进行多次显示。

    我使用the following callback directive解决了这个问题,并在回调函数内部调用了jQuery方法。

    指令:

    app.directive("repeatEnd", function(){
            return {
                restrict: "A",
                link: function (scope, element, attrs) {
                    if (scope.$last) {
                        scope.$eval(attrs.repeatEnd);
                    }
                }
            };
        });
    

    这并不能解决所有问题。仍然存在未应用 Angular 绑定的问题,因为元素是在重复结束后绑定的。为了解决这个问题,我更改了 jQuery 代码以获取 ng-repeat 中当前元素的索引,并从索引中调用我的数据:

    $scope.repeatOver = function(){
    
            $('#myCarousel').carousel({
              interval: false
            });
    
            $('.carousel .item').each(function(index){
              var next = $(this).next();
              var indexNext = index+1;
              var indexNextNext = index+2;
              if (!next.length) {
                next = $(this).siblings(':first');
                indexNext = 0;
                indexNextNext = 1;
              }
              next.children(':first-child').clone().appendTo($(this));
              // Change the source of the element
              $(this).children(':first-child').next()[0].getElementsByTagName('img')[0].src = $scope.image[indexNext];
    
              if (next.next().length>0) {
                next.next().children(':first-child').clone().appendTo($(this));
                // Change the source of the element
                $(this).children(':first-child').next().next()[0].getElementsByTagName('img')[0].src = $scope.image[indexNextNext];
              }
              else {
                indexNextNext = 0;
                $(this).siblings(':first').children(':first-child').clone().appendTo($(this));
                // Change the source of the element
                $(this).children(':first-child').next().next()[0].getElementsByTagName('img')[0].src = $scope.image[indexNextNext];
              }
            });
        }
    

    【讨论】: