Bootstrap carousel indicators out of the main div not switching automatically
DEMO
Well you can make use of slide.bs.carousel
option of bootstrap carousel
and make the respective indicators active
depending on the current slide as below:
var $carousel = $('#myCarousel'); //get a reference
$carousel.carousel();
$carousel.bind('slide.bs.carousel', function (e) { //attach its event
var current=$(e.target).find('.item.active'); //get the current active slide
$('.carousel-indicators li').removeClass('active') //remove active class from all the li of carousel indicator
var indx=$(current).index(); //get its index
if((indx+2)>$('.carousel-indicators li').length)
indx=-1 //if index exceeds total length of indicators present set it to -1
$('.carousel-indicators li:nth-child('+(indx+2)+')').addClass('active');//set the respective indicator active
});
UPDATE
The answer given above just shows how to make indicators active
when they are placed outside the carousel
. It is not working while click
since I haven't handled click event for carousel indicators.. Below update fixes the same.
UPDATED DEMO
var $carousel = $('#myCarousel');
$carousel.carousel();
var handled=false;//global variable
$carousel.bind('slide.bs.carousel', function (e) {
var current=$(e.target).find('.item.active');
var indx=$(current).index();
if((indx+2)>$('.carousel-indicators li').length)
indx=-1
if(!handled)
{
$('.carousel-indicators li').removeClass('active')
$('.carousel-indicators li:nth-child('+(indx+2)+')').addClass('active');
}
else
{
handled=!handled;//if handled=true make it back to false to work normally.
}
});
$(".carousel-indicators li").on('click',function(){
//Click event for indicators
$(this).addClass('active').siblings().removeClass('active');
//remove siblings active class and add it to current clicked item
handled=true; //set global variable to true to identify whether indicator changing was handled or not.
});
For Bootstrap 5
#myCarousel
is the ID of carousel whereas #indicators
is the ID of parent div of indicators.
let myCarousel = document.querySelector('#myCarousel');
myCarousel.addEventListener('slide.bs.carousel', (event) => {
let elementChildrens = document.querySelector("#indicators").children;
elementChildrens.item(event.from).classList.remove("active");
elementChildrens.item(event.to).classList.add("active");
});
HTML for Indicators:
<div id="indicators" class="carousel-indicators">
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1" aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2" aria-label="Slide 3"></button>
</div>
HTML for Carousel:
<div id="myCarousel" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="..." class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
</div>
</div>
</div>
You can use following code also for bootstrap4
$('#your-slide-div').on('slide.bs.carousel', function () {
$holder = $( ".carousel-indicators li.active" );
$holder.next( "li" ).addClass("active");
if($holder.is(':last-child'))
{
$holder.removeClass("active");
$(".carousel-indicators li:first").addClass("active");
}
$holder.removeClass("active");
});
Here an even more simplified example of Guruprasad Rao answer to make the indicators work if they are outside the main carousel div. It works with every element that has the data-target
property, not just li
$('.carousel').bind('slide.bs.carousel', function (e) {
var index = $(e.relatedTarget).index();
$('[data-target="#' + $(this).prop('id') + '"]').each(function (i) {
if (i === index) {
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
});
});