jstorm31 jstorm31 - 6 months ago 30
jQuery Question

Bootstrap carousel more slides linked to one indicator

I am using Bootstrap carousel control and I need to use less indicators than slides. So for example for slide 1 - 3 the first indicator will be active. When I click to another indicator, it will skip to slide 4.

I tried to solve it by having all of indicators in HTML, but hiding some of them with

display: none
. Then with JS find active slide, remove
.active
class and add it to the right indicator.

HTML

<!-- Indicators -->
<ul class="carousel-indicators">
<!-- For these three only #a indicator should be active -->
<li id="a" data-target="#carousel" data-slide-to="0" class="active"></li>
<li id="a1" class="hidden" data-target="#carousel" data-slide-to="1"></li>
<li id="a2" class="hidden" data-target="#carousel" data-slide-to="2"></li>

<!-- another group -->
<li id="b" data-target="#carousel" data-slide-to="3"></li>
</ul>


JavaScript

$('#carousel').on('slid.bs.carousel', function (e) {
if ($("#a1").hasClass("active")) {
$("#a1").removeClass("active");
$("#a").addClass("active");
} else if ($("#a2").hasClass("active")) {
$("#a2").removeClass("active");
$("#a").addClass("active");
}
});


Here is an example - https://jsfiddle.net/9x5u7kjx/2/

I think this is not elegant solution at all, so is there any better way to do it?




EDIT:
I will try to explain it more clearly.

There are for example 12 slides, which slide automatically one by one. They can be controlled by arrows (left and right). But there are only 4 indicators (those circles below carousel). And for slide 1 - 3 the first indicator should be active, for 4 - 6 the second one and so on.

So I can slide one by one item using arrows, but when I click second indicator the carousel will skip to slide 4.

Have a look at the example, it works as it should, but I think this could be solved better.

Answer

Carousel with 4 indicators instead of 12

1. Standard indicators. CSS trick

Bootstrap's indicators are transparent except the active one. So I put them on top of each other and received two stacks of three indicators each.

The second and third indicators lie below the first indicator. Therefore, just the first indicator reacts on the click.

.carousel-indicators > li:nth-of-type(3n+2),
.carousel-indicators > li:nth-of-type(3n+3) {
  margin-left: -15px;
  position: relative;
  z-index: -1;
}

Bootstrap's active indicator is wider by 2 pixels than inactive one. It needs to move 1 pixel more than the others.

.carousel-indicators > li.active:nth-of-type(3n+2),
.carousel-indicators > li.active:nth-of-type(3n+3) {
  margin-left: -16px;
}

Check the result:

https://jsfiddle.net/glebkema/346n1cwo/

@import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');

.carousel-inner > .item > img {
  width: 100%;
}
.carousel-indicators > li:nth-of-type(3n+2),
.carousel-indicators > li:nth-of-type(3n+3) {
  margin-left: -15px;
  position: relative;
  z-index: -1;
}
.carousel-indicators > li.active:nth-of-type(3n+2),
.carousel-indicators > li.active:nth-of-type(3n+3) {
  margin-left: -16px;
}
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
  <!-- Indicators -->
  <ol class="carousel-indicators">
    <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
    <li data-target="#carousel-example-generic" data-slide-to="1"></li>
    <li data-target="#carousel-example-generic" data-slide-to="2"></li>
    <li data-target="#carousel-example-generic" data-slide-to="3"></li>
    <li data-target="#carousel-example-generic" data-slide-to="4"></li>
    <li data-target="#carousel-example-generic" data-slide-to="5"></li>
    <li data-target="#carousel-example-generic" data-slide-to="6"></li>
    <li data-target="#carousel-example-generic" data-slide-to="7"></li>
    <li data-target="#carousel-example-generic" data-slide-to="8"></li>
    <li data-target="#carousel-example-generic" data-slide-to="9"></li>
    <li data-target="#carousel-example-generic" data-slide-to="10"></li>
    <li data-target="#carousel-example-generic" data-slide-to="11"></li>
  </ol>

  <!-- Wrapper for slides -->
  <div class="carousel-inner" role="listbox">
    <div class="item active"><img class="img-responsive" src="//placehold.it/1200x300/9c6/fff/?text=0" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/c69/fff/?text=1" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/69c/fff/?text=2" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/9c6/fff/?text=3" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/c69/fff/?text=4" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/69c/fff/?text=5" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/9c6/fff/?text=6" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/c69/fff/?text=7" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/69c/fff/?text=8" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/9c6/fff/?text=9" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/c69/fff/?text=10" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/69c/fff/?text=11" alt=""></div>
  </div>

  <!-- Controls -->
  <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next"> 
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

<div class="alert text-center">
  Bootstrap carousel with 4 standard indicators instead of 12 by CSS trick
</div>
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>


2. Custom indicators. jQuery

https://jsfiddle.net/glebkema/0L97fuzw/

$( document ).ready(function() {
  var CLASS_CAROUSEL    = '#carousel-example-generic';
  var CLASS_INDICATORS  = '#carousel-indicators';
  var CLASS_ACTIVE      = CLASS_INDICATORS + '>li.active';
  var selectCarousel    = $(CLASS_CAROUSEL); 

  selectCarousel.on('slide.bs.carousel', function (e) {
    var indexTarget = $(e.relatedTarget).index();
    indexTarget = indexTarget - indexTarget % 3;
    
    var selectTarget = $(CLASS_INDICATORS + '>li[data-slide-to="' + indexTarget + '"]');
    if ( !selectTarget.hasClass('active') ) {
      $(CLASS_ACTIVE).removeClass('active');
      selectTarget.addClass('active');
    }
  });
});
@import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');

.carousel-inner > .item > img {
  width: 100%;
}

/* design */
.carousel-indicators > li,
.carousel-indicators > li.active{
  border-radius: 0;
  border-width: 1px;
  height: 30px;
  line-height: 28px; /* = height - 2 * border-width */
  margin: 0 1px; 
  text-indent: 0;
  width: 70px;
}
.carousel-indicators > li {
  border-color: #666;
  color: #666;
}
.carousel-indicators > li:hover {
  background-color: #fee;
}
.carousel-indicators > li.active {
  border-color: red;
  color: red;
}

/* location */
.carousel-indicators {
  margin: 6px 0;
  position: static;
  width: 100%;
}
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
  <!-- Wrapper for slides -->
  <div class="carousel-inner" role="listbox">
    <div class="item active"><img class="img-responsive" src="//placehold.it/1200x300/9c6/fff/?text=0" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/c69/fff/?text=1" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/69c/fff/?text=2" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/9c6/fff/?text=3" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/c69/fff/?text=4" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/69c/fff/?text=5" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/9c6/fff/?text=6" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/c69/fff/?text=7" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/69c/fff/?text=8" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/9c6/fff/?text=9" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/c69/fff/?text=10" alt=""></div>
    <div class="item"><img class="img-responsive" src="//placehold.it/1200x300/69c/fff/?text=11" alt=""></div>
  </div>

  <!-- Controls -->
  <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next"> 
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

<!-- Indicators -->
<ol id="carousel-indicators" class="carousel-indicators">
  <li data-target="#carousel-example-generic" data-slide-to="0" class="active">0 - 2</li>
  <li data-target="#carousel-example-generic" data-slide-to="3">3 - 5</li>
  <li data-target="#carousel-example-generic" data-slide-to="6">6 - 8</li>
  <li data-target="#carousel-example-generic" data-slide-to="9">9 - 11</li>
</ol>

<div class="alert text-center">
  Bootsrap carousel with 4 custom indicators instead of 12 by jQuery
</div>
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>