I'm kind of stumped. :) I'm new to Javascript, but have typically found lots of great help on the net when I Googled. The best help I could come up with this time was here, but the docs said it was better to post a new question than sidetrack the original post. So, here's my question: I'm using Bootstrap3's carousel I'm trying to pick a random starting image, and then continue with random images after that. I've figured out how to pick the first slide, but can't figure out how to pick the next slide. As it stands, it just continues to cycle through the show.
<div id="myCarousel" class="carousel slide" data-wrap="true" data-ride="carousel">
<!-- Slider Content (Wrapper for slides )-->
<div class="carousel-inner">
<div class="item">
<img src="images/slides/AAA.jpg" alt="AAA" />
</div>
<div class="item">
<img src="images/slides/BBB.jpg" alt="BBB" />
</div>
<div class="item">
<img src="images/slides/CCC.jpg" alt="CCC" />
</div>
<div class="item">
<img src="images/slides/DDD.jpg" alt="DDD" />
</div>
<div class="active item">
<img src="images/slides/EEE.jpg" alt="EEE" />
</div>
</div>
</div>
<script src="js/bootstrap.js"></script>
<script type='text/javascript'>
$(document).ready(function() {
/* Pick a random number and apply it to the first slide in the slideshow item */
$('.item').eq(Math.floor((Math.random() * $('.item').length))).addClass("active");
/* Pick random next slide */
$('#myCarousel').carousel(Math.floor((Math.random() * $('.item').length))));
});
</script>
Thanks. :)
jQuery
var currentSlide;
var rand;
$(document).ready(function() {
currentSlide = Math.floor((Math.random() * $('.item').length));
rand = currentSlide;
$('#myCarousel').carousel(currentSlide);
$('#myCarousel').fadeIn(1000);
setInterval(function(){
while(rand == currentSlide){
rand = Math.floor((Math.random() * $('.item').length));
}
currentSlide = rand;
$('#myCarousel').carousel(rand);
},3000);
});
CSS
#myCarousel {
display:none;
}
HTML
<div id="myCarousel" class="carousel slide" data-wrap="true">
....
Well here is an example of how I would do it... I also accounted for the possibility of it randomly changing to the same slide.
http://www.bootply.com/99052
You will notice however that depending on which slide is chosen the carousel will transition either left or right.. The bootstrap carousel was designed to display linear images. There may be a way to manipulate the order of the items using jQuery so that it always slides the same way. If you are looking for that it could be done but would take some work and would probably be best handled in another question.
Als you can remove the data-ride="carousel" from you html and that will make it so the carousel will initialize without cycling.
Related
I'm trying to following this but it's 6 years old. Have things change 'cause my js doesn't seem to get triggered when the URL contains #slide_ ?
Linking to a certain bootstrap carousel slide from another page
My code on page2:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<!-- Core theme CSS (includes Bootstrap)-->
<link href="css/styles.css?v20221223=1" rel="stylesheet" />
</head>
<body>
<!-- Carousel Wrapper-->
<div id="myCarousel" class="carousel carousel-dark slide" data-bs-interval="false" data-ride="carousel" data-pause="hover">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="https://www.w3schools.com/bootstrap/chicago.jpg" alt="..." class="d-block img-fluid">
</div>
<div class="carousel-item">
<img src="https://www.w3schools.com/bootstrap/la.jpg" alt="..." class="d-block img-fluid">
</div>
<div class="carousel-item">
<img src="https://www.w3schools.com/bootstrap/ny.jpg" alt="..." class="d-block img-fluid">
</div>
</div>
</div>
</div>
<!-- END Carousel Wrapper-->
<!-- Bootstrap core JS - versionas as of Dec 2022-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<!-- JS for loading a particular slide from another page -->
<script>
function qs(key) {
key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&");
var match = location.search.match(new RegExp("[?&]" + key + "=([^&]+)(&|$)"));
var slide = match && decodeURIComponent(match[1].replace(/\+/g, " "));
if (Math.floor(slide) == slide && $.isNumeric(slide))
return parseInt(slide);
else
return 0;
}
//why this isn't working???
$('#myCarousel').carousel(qs('slide'));
</script>
</body>
</html>
And the link on page 1
slide 2
I'm stuck...
In your example you added your JS in page 2, but your link redirects the user to page 1. Make sure you get your URLs correct, so based on your example it should be slide 2 on page 1.
Furthermore, the function function qs(key) {..} extracts the hash on ? not on #.
Don't worry though, what you want is simple, so I wrote a quick example for you.
Explaining the snippet below
You can achieve your desired functionality without needing jQuery.
In my example I created a function called getSlideNumber(). This first checks if the location hash exists, then we get it's value and split it on the = to get to the slide number. After that, we convert value into an integer using parseInt(). If that fails, the parseInt() function returns NaN so we also make sure our slide number is in fact an integer before we return it using Number.isInteger(). This way we protect ourselves against any malicious hashes.
We then call that function to get our slide number and use Bootstrap's method getOrCreateInstance to get the carousal instance that's on our page and make it cycle to the slide number using to().
And that's all it is!
Usage
We can't extract a hash in a snippet, so I don't call the function getSlideNumber() in my example. Therefore, make sure you delete the line const slideNumber = 2 and remove the // in front of the line above it when you want to use this code for your own project. Like so:
const slideNumber = getSlideNumber();
const element = document.querySelector('#carouselExample')
const caroursal = bootstrap.Carousel.getOrCreateInstance(element).to(slideNumber);
Also, note that the first slide of a carousal has an index of 0, similar to an array.
Lastly, you can edit the carousal HTML as you please, I used the basic example from the documentation.
The snippet
window.onload = function(){
function getSlideNumber() {
if(location.hash && location.hash.length) {
const value = location.hash.substr(1).split('=')[1];
const int = parseInt(value);
if (Number.isInteger(int)) {
return int;
} else {
return 0;
}
}
return 0;
}
//const slideNumber = getSlideNumber();
const slideNumber = 2; // Uncomment the line above and remove this line, it's only for demonstration purposes.
const element = document.querySelector('#carouselExample')
const caroursal = bootstrap.Carousel.getOrCreateInstance(element).to(slideNumber);
};
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<div class="container">
<div id="carouselExample" class="carousel slide">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="https://www.w3schools.com/bootstrap/chicago.jpg" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="https://www.w3schools.com/bootstrap/la.jpg" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="https://www.w3schools.com/bootstrap/ny.jpg" class="d-block w-100" alt="...">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExample" 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="#carouselExample" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
Solution with jQuery
But wait! What if you can't live without jQuery? Worry no more, use this instead:
$(document).ready(function() {
function getSlideNumber() {
if(location.hash && location.hash.length) {
const value = location.hash.substr(1).split('=')[1];
const int = parseInt(value);
if (Number.isInteger(int)) {
return int;
} else {
return 0;
}
}
return 0;
}
const slideNumber = getSlideNumber();
$("#carouselExample").carousel(slideNumber);
});
Multiple carousals on one page
Assuming all carousals should be set to slideNumber we can target all carousals on the page with the class .carousal and then loop through them, like so:
const slideNumber = getSlideNumber();
const carousels = document.querySelectorAll('.carousel');
carousels.forEach(carousel => {
bootstrap.Carousel.getOrCreateInstance(carousel).to(slideNumber);
});
This works fine, but all carousals will cycle to the same slideNumber. If say your hash contains multiple values like page2.html#slide=2&slide=3 and you want the second carousal to cycle to slide 3 you would have to make getSlideNumber() return an object with all the slide numbers, then get the id of carousal inside the forEach loop and apply the corresponding slide number you have in the previous mentioned object in the to() method on the carousal id. That would be just one possible way of doing it.
Hope that helps. Good luck!
I have made a carousel which contain three images as a group.
For example:
<[1][2][3]>
Currently when you hit right arrow, it only goes one image at a time.
<[2][3][4]>
I would like to know when clicking on the arrow, how to show/advance to the next three images.
Like this:
<[4][5][6]>
Here's some code:
<div class="carousel slide" id="myCarousel" data-interval="false">
<div class="carousel-inner">
<div class="item active">
<div class="col-md-4">image1</div>
</div>
<div class="item">
<div class="col-md-4">image2</div>
</div>
<div class="item">
<div class="col-md-4">image3</div>
</div>
<div class="item">
<div class="col-md-4">image4</div>
</div>
<div class="item">
<div class="col-md-4">image5</div>
</div>
<div class="item">
<div class="col-md-4">image6</div>
</div>
</div></div>
<script>
$('.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));
}
});
</script>
Looking at boostrap's specifications, there doesn't seem to be an option to modify this manually.You'd have to try to override it somehow, which is probably gonna be ugly and a lot of work.
I would suggest just using a library where this parameter is adjustable with only one variable. I've used slick carousel before, and it's very easy to use. If you look at the example "multiple-items" it looks like exactly what you're looking for.
$('.multiple-items').slick({
infinite: true,
slidesToShow: 3,
slidesToScroll: 3
});
I have this html code:
<div class="slider" id="mySlider" >
<div class="slide-group">
<div class="slide">
<img src="images/image1.jpg">
</div>
<div class="slide">
<img src="images/image2.jpg">
</div>
<div class="slide">
<img src="images/image3.jpg">
</div>
</div>
</div>
After every div with class slide there's the img as you can see above.
Using jquery, how can I get it to auto slide between images?
You can use setInterval() to cycle through the slides.
Set it so after x time move to the next slide
The snippet below isn't functioning completely properly, but it gives you a general idea
$(document).ready(function(){
window.setInterval(nextSlide, 1000);
});
function nextSlide() {
var $cur = $('.slide.active');
var $next = $cur.next();
if(!$next) $next = $('.slide-group').children()[0];
console.log($next);
$cur.removeClass('active');
$next.addClass('active');
}
.slide {
display: none;
}
.slide.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="slider" id="mySlider" >
<div class="slide-group">
<div class="slide active">
SLIDE 1
</div>
<div class="slide">
SLIDE 2
</div>
<div class="slide">
SLIDE 3
</div>
</div>
</div>
Jon Raasch's simple jquery slideshow is the absolute classic, in my opinion. I've seen it used on many sites.
http://jonraasch.com/blog/a-simple-jquery-slideshow
His example uses a fade, but you can change it to a slide or even Ken Burns it easily enough.
http://www.dwuser.com/education/content/creating-a-jquery-image-scroller/
is just one example of tutorials for image scrollers using jquery.
Just google "jquery image scroller" then if you have further issues come back and see us :)
I have a custom slider which can rotate each image when I click the bullets. I need to make it autoplay, so I want if the page is ready, it's trigger click on the 1st bullet, 2nd, 3rd, 4th, etc and back to 1st bullet again...
but it just works for 1st and 2nd slides only.
The bullets using attr data-container for each slide id:
<nav class="thumb-nav">
<a data-container="container-1" class="thumb-nav__item" href="#"><span>1</span></a>
<a data-container="container-2" class="thumb-nav__item" href="#"><span>2</span></a>
<a data-container="container-3" class="thumb-nav__item" href="#"><span>3</span></a>
<a data-container="container-4" class="thumb-nav__item" href="#"><span>4</span></a>
</nav>
and these are the slide contents:
<div id="container-1" class="container theme-1">
<header class="intro">
<img class="intro__image" src="http://tympanus.net/Tutorials/SlidingHeaderLayout/img/header01.jpg" alt="Lava"/>
<!-- /intro__content -->
</header><!-- /intro -->
</div><!-- /container -->
<div id="container-2" class="container theme-2">
<header class="intro">
<img class="intro__image" src="http://tympanus.net/Tutorials/SlidingHeaderLayout/img/header02.jpg" alt="Road"/>
<!-- /intro__content -->
</header><!-- /intro -->
</div>
<div id="container-3" class="container theme-3">
<header class="intro">
<img class="intro__image" src="http://tympanus.net/Tutorials/SlidingHeaderLayout/img/header03.jpg" alt="Lava"/>
</header>
</div>
<div id="container-4" class="container theme-4">
<header class="intro">
<img class="intro__image" src="http://tympanus.net/Tutorials/SlidingHeaderLayout/img/header02.jpg" alt="Lava"/>
</header>
</div>
and here's my FIDDLE
Any help is going to be appreciated.
The setInterval is not supposed to be inside the forEach loop.
var pageIndex = 0;
setInterval(function() {
pageIndex ++;
if(pageIndex >= pageTriggers.length) pageIndex = 0;
navigate( pageTriggers[pageIndex] );
}, 5000);
Refer jsFiddle
Hope this helps. Let me know if your question is not answered.
Edit:
if(pageIndex >= pageTriggers.length)
Note:
I am creating a new pageIndex here, you might consider using your already defined global variable current.
First: You need to move your setInterval block outside of your outside of pageTriggers.forEach block. As you have it, it is creating a timer for each of the slides but then the first one is overriding the others (which is why it's only bouncing between your first two slides).
Second: Outside of the forEach you can't pass this to your navigate function. So you're going to need some other way of figuring out which slide to go to. That new slide is represented below by newIndex.
Solution:
setInterval(function () {
var newIndex = current + 1 >= pageTriggers.length ? 0 : current + 1
navigate(pageTriggers[newIndex]);
}, 5000);
See the fiddle.
Nice job though, I like it.
I have a simple JS Junction that stop working when the break point of my responsive website is activated (The nav var toggle/collapse at 768px, here is when the JS function stop working)
The HTML is:
<div class="mainFoto">
<img id="bigImage" src="/fotosArticulos/12578.jpg">
</div>
<div class="misProductosFotos">
<div class="foto" onclick="callImage('12578.jpg');"><img src="/Thumbs/12578.jpg"></div>
<div class="foto" onclick="callImage('30643.jpg');"><img src="/Thumbs/30643.jpg"></div>
<div class="foto" onclick="callImage('12656.jpg');"><img src="/Thumb/12656.jpg"></div>
</div>
and the JS function is
function callImage(idImage) {
var imageUrl = '/fotosArticulos/'+idImage;
$('#bigImage').attr('src', imageUrl);
}
This simple does that when click on one thumb the JS change the SRC of id="bigImage"
Why this Function stop working and how fix it?
May be this will help you.
HTML
<div class="mainFoto">
<img id="bigImage" src="/fotosArticulos/12578.jpg" />
</div>
<div class="misProductosFotos">
<div class="foto">
<img src="/Thumbs/12578.jpg" />
</div>
<div class="foto">
<img src="/Thumbs/30643.jpg" />
</div>
<div class="foto">
<img src="/Thumbs/12656.jpg" />
</div>
</div>
Script
$('.foto').click(function() {
$('#bigImage').attr('src', $(this).find('img').prop('src').replace('/Thumbs/', '/fotosArticulos/'));
})
fiddle
Thanks Guys for all your support. The issue was that when the website collapsed and get responsive there was an invisible element that overlap the Thumbs icons, that is why they did not respond, I think I blend bootstrap too soon. Thanks again :)
#anilkumar, do you think storing $(this).find('img').prop('src').replace('/Thumbs/', '/fotosArticulos/') in a variable might make things a little more human readable? Like so:
$('.foto').on('click', function() {
var changeSrc = $(this).find('img').prop('src').replace('/Thumbs/', '/fotosArticulos/');
$('#bigImage').attr('src', changeSrc);
})
#saymon, do you reckon you might be removing the #bigImage id from .mainFoto > img at the breakpoint? Or perhaps Bootstrap might be renaming the element id?