pruoccojr
pruoccojr

Reputation: 482

Can a bootstrap carousel rotate through only some of the slides?

I have a vanilla carousel straight from the bootstrap site.

$('.carousel').carousel({
  interval: 2000
})

It has 5 slides with 5 indicators:

1 2 3 A B

I would like the carousel to automatically loop through slides 1 2 and 3, then repeat. However, if I click on the indicators for slides A or B, I would like to move to that slide and pause the carousel.

How can I limit the auto rotate to just slides 1 2 and 3?

Upvotes: 2

Views: 1062

Answers (1)

tao
tao

Reputation: 90013

  1. You need to tap into the slide event, just after it starts and tell it to go to first slide if the currently active slide is the one that should reset the slider.
  2. You also need to store if the current slide event is an auto-play slide or initiated by a slider control, because you want to allow controls to go to slides that are otherwise off limits
  3. And also, you need to pause the slider after you reached any of the slides past the cycle reset point and play the slider if you're below (to make it restart auto-playing after you return from a slide that paused it).

But apparently, Bootstrap carousel doesn't like a new slide event to be initiated from inside an existing one, so we need to call .preventDefault() on the current one to be able to initiate another.

aP (autoPlaying) variable stores if the current slide event has been initiated by interaction with a slider control,
cR (cycleReset) stores the index of the slide that should reset the cycle and
sL (selector) should be your slider's selector.

Here it is:

var sL = '#z', // slider selector
    aP = true, // autoPlaying
    cR = 2;    // cycleReset

$(sL)
    .on('click', '.carousel-indicators,.carousel-control', function() {
        // autoplaying off when a control is clicked
        aP = false;
    })
    .on('slide.bs.carousel', function(e) {
        // if on the cycle reset slide and auto-playing...
        if (($(sL + ' .active').index() == cR) && aP) {
            // ...we stop the current slide event...
            e.preventDefault();
            // ...turn off autoplaying (to prevent an infinite loop)...
            aP = false;
            // ...and go to first slide;
            $(sL).carousel(0)
        } else {
            // or we set auto-playing true (for next slide event).
            aP = true;
        }
    })
    .on('slid.bs.carousel', function(e) {
        // when a slide event finished, if we arrived on a slide
        // that's after the cycle reset slide, we pause the slider
        // otherwise we play (cycle) it
        $(sL).carousel($(sL + ' .active').index() > cR ? 'pause' : 'cycle');
    });

Working example:

var sL = '#z',
    aP = true,
    cR = 2;

$(sL)
    .on('click', '.carousel-indicators,.carousel-control', function() {
        aP = false;
    })
    .on('slide.bs.carousel', function(e) {
        if (($(sL + ' .active').index() == cR) && aP) {
            e.preventDefault();
            aP = false;
            $(sL).carousel(0)
        } else {
            aP = true;
        }
    })
    .on('slid.bs.carousel', function(e) {
        $(sL).carousel($(sL + ' .active').index() > cR ? 'pause' : 'cycle');
    });
body {margin: 0;}
.item img {
  width: 100%;
  height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div id="z" class="carousel slide" data-ride="carousel">
  <!-- Indicators -->
  <ol class="carousel-indicators">
    <li data-target="#z" data-slide-to="0" class="active"></li>
    <li data-target="#z" data-slide-to="1"></li>
    <li data-target="#z" data-slide-to="2"></li>
    <li data-target="#z" data-slide-to="3"></li>
    <li data-target="#z" data-slide-to="4"></li>
  </ol>

  <!-- Wrapper for slides -->
  <div class="carousel-inner" role="listbox">
    <div class="item active">
      <img src="http://lorempixel.com/g/600/210/fashion" alt="Chania">
    </div>

    <div class="item">
      <img src="http://lorempixel.com/g/600/210/fashion" alt="Chania">
    </div>

    <div class="item">
      <img src="http://lorempixel.com/g/600/210/fashion" alt="Flower">
    </div>

    <div class="item">
      <img src="http://lorempixel.com/g/600/210/fashion" alt="Flower">
    </div>
    
    <div class="item">
      <img src="http://lorempixel.com/g/600/210/fashion" alt="Flower">
    </div>
  </div>

  <!-- Left and right controls -->
  <a class="left carousel-control" href="#z" 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="#z" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

Upvotes: 1

Related Questions