This might be a remarkable stupid question. I use setInterval to measure the total time that a user looks at a specific image in a bootstrap carousel, the total interval time, and the current index of the image.
In addition, I want to measure the time between the event when the picture slides into view and when the picture slides out of view in the bootstrap carousel. Not only the total time but also the time of the single event when the picture is visible.
Until now, I could not figure out a way to achieve my goal without completely changing the whole script. I thought about using setTimeout().
var intervalTime = 10;
var timesMilliseconds = {
0: 0
};
var intervalMilliseconds = 0;
var currentSlideIndex = 0;
var interval;
var currentIndex;
var currentTotalTime;
var currentIntervalTime;
var search_behavior = {};
$('document').ready(function() {
interval = setInterval(function() {
if (timesMilliseconds.hasOwnProperty(currentSlideIndex)) {
timesMilliseconds[currentSlideIndex] += intervalTime;
intervalMilliseconds += intervalTime;
} else {
timesMilliseconds[currentSlideIndex] = intervalTime;
intervalMilliseconds += intervalTime;
}
}, intervalTime);
$('#carouselExampleControls').on('slide.bs.carousel', function(event) {
currentIndex = currentSlideIndex.toString();
currentTotalTime = timesMilliseconds[currentSlideIndex].toString();
currentIntervalTime = intervalMilliseconds;
currentSlideIndex = event.to;
search_behavior = {
current_index: currentIndex,
current_interval: currentIntervalTime,
total_time_index: currentTotalTime,
}
console.log(search_behavior)
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
<div id="carouselExampleControls" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="https://picsum.photos/200/300" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="https://picsum.photos/200/300" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="https://picsum.photos/200/300" class="d-block w-100" alt="...">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
Related
In this code, scrolling is not working. Around 25-30 (image count is not fixed )images will be added from the admin panel each week that will replace the previous images and that will be displayed here. only the latest images will be visible in front Images get properly fetched but scrolling is not working. I think there is some issue in the javascript code. Please help me to resolve it.
/*
Carousel
*/
$('#carousel-example').on('slide.bs.carousel', function(e) {
/*
CC 2.0 License Iatek LLC 2018 - Attribution required
*/
var $e = $(e.relatedTarget);
var idx = $e.index();
var itemsPerSlide = 5;
var totalItems = $('.carousel-item').length;
if (idx >= totalItems - (itemsPerSlide - 1)) {
var it = itemsPerSlide - (totalItems - idx);
for (var i = 0; i < it; i++) {
// append slides to end
if (e.direction == "left") {
$('.carousel-item').eq(i).appendTo('.carousel-inner');
} else {
$('.carousel-item').eq(0).appendTo('.carousel-inner');
}
}
}
});
<!-- Cartoon Carousel -->
<section>
<div class="cartoon">
<div class="top-content">
<div class="container-fluid">
<div id="carousel-example" class="carousel slide" data-ride="carousel">
<!-- slides -->
<div class="carousel-inner row w-100 mx-auto" role="listbox">
<?php
if(sizeof($cartoons_category_data) > 0){
for($i = 0; $i< count($cartoons_category_data) ; $i++){
?>
<div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3 active">
<img src="<?php echo base_url('assets/uploads/library/'.$cartoons_category_data[$i]); ?>" class="img-fluid mx-auto d-block" alt="img1">
</div>
<?php
} //for
} ?>
</div>
<a class="carousel-control-prev" href="#carousel-example" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true" style="background-color: #ffa500;
padding: 15px;"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carousel-example" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true" style="background-color: #ffa500;
padding: 15px;"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</div>
</section>
I am making a character select screen and I want the bootstrap carousel arrows to also change the text in the scroll to match each character. Right now the scroll is a separate component but I'm open to putting them on the same page.
I was trying to grab it by the class "active" since that came with the bootstrap carousel and populating from a data.json, but it isn't working. Open to other (hopefully easier) ideas as well!!
state = {
data: characters,
curCharacter: {},
}
componentDidMount() {
var cur = this.state.data[0].description;
this.setState({ curCharacter: this.state.data[0] });
console.log(this.state.curCharacter)
}
characterSelect = (e) => {
e.preventDefault()
var cur = document.getElementsByClassName("active")
console.log("activ1", cur)
var newClass = cur[0].children[0].alt
console.log("activ2", newClass);
var arr = this.state.data;
console.log(arr);
for (let i = 0; i < arr.length; i++) {
console.log(arr[i], arr[i + 2]);
if (newClass == arr[i].class) {
this.setState({ curCharacter: arr[i] });
console.log(this.state.curCharacter)
}
}
}
render() {
return (
<div className="charContain">
<div className="row">
<div className="col-md-6">
<div id="carouselExampleControls" class="sprite carousel slide" data-ride="carousel" data-interval="false" >
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block h-100" src="https://i.imgur.com/ODs4zDn.gif" alt="Warrior" />
</div>
<div class="carousel-item">
<img class="d-block h-100" src="https://i.imgur.com/huVIPkL.png" alt="Archer" />
</div>
<div class="carousel-item">
<img class="d-block h-100" src="https://i.imgur.com/bKvuY6T.png" alt="Warrior" />
</div>
<div class="carousel-item">
<img class="d-block h-100" src="https://i.imgur.com/pIHmyE4.png" alt="Mage" />
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" onClick={this.characterSelect} href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
<button onClick={handleButtonChoose} className="choose">Choose Character</button>
</div>
<div className="col-md-6">
<Scroll
text={this.state.description}
/>
</div>
</div>
</div>
)
}
}
export default Character
Thanks in advance!!
I have a carousel and within that carousel I have cards in it and each card should have at least horizontally aligned to it but in my case it aligns vertically.
The data are from the API itself.
/*
container.innerText = "It's working!\n\n";
container.innerText += 'Found sample products:\n';
products.forEach(product => (container.innerText += `- ${product.title}\n`));
*/
var products = [
{
"imageUrl": "http://lorempixel.com/g/400/200",
"title": "CANDECOR"
},
{
"imageUrl": "http://lorempixel.com/g/400/200",
"title": "ZOLAREX"
},
{
"imageUrl": "http://lorempixel.com/g/400/200",
"title": "HATOLOGY"
},
{
"imageUrl": "http://lorempixel.com/g/400/200",
"title": "EGYPTO"
},
{
"imageUrl": "http://lorempixel.com/g/400/200",
"title": "BULLZONE"
},
{
"imageUrl": "http://lorempixel.com/g/400/200",
"title": "NIKUDA"
}
];
var countFirstThree = true;
var isCardSet = true;
var setCount = 1;
for (var i = 1; i < products.length; i++) {
if (isCardSet) {
$('.carousel-inner').append(insertCarouselItem(countFirstThree, setCount));
isCardSet = false;
}
if (i % 3 == 0) {
$('#set-' + setCount).append(insertCards(products[i - 1].id, products[i - 1].imageUrl, products[i - 1].title));
$('#set-' + setCount).append('</div>');
countFirstThree = false;
isCardSet = true;
setCount++;
} else {
$('#set-' + setCount).append(insertCards(products[i - 1].id, products[i - 1].imageUrl, products[i - 1].title));
}
}
function getUrlImage(url) {
const host = 'http://localhost:8181';
return "http://lorempixel.com/g/400/200";
}
function insertCarouselItem(isActive, set) {
var active = isActive ? ' active' : '';
var result = `<div id="set-${set}" class="carousel-item${active}">`;
return result;
}
function insertCards(id, imageUrl, title) {
var result = `
<div id="${id}" class="card" style="width: 300px;">
<img class="card-img-top" src="${getUrlImage(imageUrl)}">
<div class="card-body">
<h3 class="card-title">${title}</h3>
<button class="btn btn-primary">Add to cart</button>
</div>
</div>`;
return result;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="container-fluid">
<div id="productCarousel" class="carousel slide" data-ride="carousel" data-interval="false">
<div class="carousel-inner">
</div>
<a class="carousel-control-prev" href="#productCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#productCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
but the result that I made is like this:
What I want to achieve is that, I want the cards aligned horizontally.
Try adding d-flex to your carousel-inner div
p {
background: red;
}
.carousel-item {
display: block !important;
float: none !important;
width: auto !important;
margin-right: 0 !important;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="container-fluid">
<div class="carousel slide">
<div class="carousel-inner d-flex">
<div class="carousel-item">
<div id="123" class="card" style="width: 300px;">
<img class="card-img-top" src="${getUrlImage(imageUrl)}">
<div class="card-body">
<h3 class="card-title">Title</h3>
<button class="btn btn-primary">Add to cart</button>
</div>
</div>
</div>
<div class="carousel-item">
<div id="321" class="card" style="width: 300px;">
<img class="card-img-top" src="${getUrlImage(imageUrl)}">
<div class="card-body">
<h3 class="card-title">Title</h3>
<button class="btn btn-primary">Add to cart</button>
</div>
</div>
</div>
</div>
</div>
</div>
`
I did get the JS code from: netgloo
JS:
var checkitem = function() {
var $this;
$this = $("#");
if ($("#diapos .carousel-inner .item:first").hasClass("active")) {
$this.children(".left").hide();
$this.children(".right").show();
} else if ($("#diapos .carousel-inner .item:last").hasClass("active")) {
$this.children(".right").hide();
$this.children(".left").show();
} else {
$this.children(".carousel-control").show();
}
};
checkitem();
$("#diapos").on("slid.bs.carousel", "", checkitem);
HTML:
<div id="diapos" class="carousel paper2 slide" data-ride="carousel">
<!-- diapos -->
<div class="carousel-inner" role="listbox">
<div class="overlay"></div>
<div class="item active" id="first">
<img src="img/01.jpg" alt="...">
</div>
<div class="item" id="second">
<img src="img/02.jpg" alt="...">
</div>
<div class="item" id="last">
<img src="img/03.jpg" alt="...">
</div>
</div>
</div>
<a class="left carousel-control" href="#diapos" 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="#diapos" role="button" data-slide="next"><span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span><span class="sr-only">Next</span></a>
The code is not hidding the respective controls.
There are no other carousels in the document.
By the way, what's the function of this piece of HTML?:
<div class="overlay"></div>
The id of the carousel div is "diapos". So this on the third line should be assigned to that, as 'left' and 'right' are its immediate children :
var checkitem = function() {
var $this;
$this = $("#diapos"); // this line needs to be changed
if ($("#diapos .carousel-inner .item:first").hasClass("active")) {
$this.children(".left").hide();
//continue as before from here
Also, you probably forgot to close the 'diapos' div!
In Bootstrap 3, with jQuery is there a way to sort by the index of my carousel and add custom intervals of each slide so that I can have one slide 10000ms and another 500ms etc?
I know you can set the data-interval attribute but this sets the speed for all slides as you can't add a custom interval attribute to each item.
data-interval="3000"
My carousel is setup like this:
<div id="carousel" class="carousel slide">
<div class="carousel-inner">
<div class="item active">
<a href="#">
<img class="img-responsive" src="">
</a>
</div>
<div class="item">
<a href="#">
<img class="img-responsive" src="">
</a>
</div>
<div class="item">
<a href="#">
<img class="img-responsive" src="">
</a>
</div>
<div class="item">
<a href="#" >
<img class="img-responsive" src="">
</a>
</div>
</div>
You can create a custom attribute that denotes how long the slide should be visible for, pull that out for the active item on the slide.bs.carousel or slid.bs.carousel events (whichever you prefer/works best for you), then set it as a timeout to go to the next slide.
$('#carousel-example-generic').on('slide.bs.carousel', function() {
var interval = $('div.item.active').attr('duration');
setTimeout(function() {
$('.carousel').carousel('next');
}, interval);
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<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>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active" duration="3000">
<img src="http://placehold.it/400x200" alt="..." />
<div class="carousel-caption">
First
</div>
</div>
<div class="item" duration="2000">
<img src="http://placehold.it/400x200" alt="..." />
<div class="carousel-caption">
Second
</div>
</div>
<div class="item" duration="1000">
<img src="http://placehold.it/400x200" alt="..." />
<div class="carousel-caption">
Third
</div>
</div>
<div class="item" duration="500">
<img src="http://placehold.it/400x200" alt="..." />
<div class="carousel-caption">
Fourth
</div>
</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>
The solution given by #MattD seems to work well, alternatively you could overwrite the slide function of the carousel plugin bu using the following code:
<script src="js/carousel.js"></script>
<script>
$.fn.carousel.Constructor.prototype.cycle = function (e) {
e || (this.paused = false)
this.interval && clearInterval(this.interval)
this.options.interval
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), this.$element.find('.item.active').data('interval') || this.options.interval))
return this
}
</script>
The above enables you to set the interval per slide leveraging the data-interval attribute as shown below:
<div class="item" data-interval="500">
The answer by #Bass didn't quite work for me. It was actually taking the interval of the slide BEFORE, so my updated version is:
function overwriteBootstrapCarouselCycleFunction() {
$.fn.carousel.Constructor.prototype.cycle = function (e) {
e || (this.paused = false)
this.interval && clearInterval(this.interval)
var element_to_slide;
var duration;
if (this.$element.find('.item.next').size() === 1) { // once the first slide has started the interval until the next call is on the slide with the 'next' class
element_to_slide = this.$element.find('.item.next')
} else {
element_to_slide = this.$element.find('.item.active') // just before the cycle starts, there is no 'next' but the first slide is marked active, use that
}
duration = element_to_slide.data('interval') // if the element has a pre-configured interval use it
if(typeof duration === "undefined") duration = this.options.interval // otherwise use the default for the slideshow
this.options.interval
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), duration ))
$.fn.carousel.Constructor.prototype.overwritten = true
return this
}
}
document.addEventListener('DOMContentLoaded', () => {
if (!$.fn.carousel.Constructor.prototype.overwritten)
overwriteBootstrapCarouselCycleFunction()
var id = '#{carousel_id}'
$('#' + id + ' #pause-control').click(function(){
pauseSlideshow(id)
})
$('#' + id + ' #play-control').click(function(){
playSlideshow(id)
})
})