Home Page Banner Slideshow Not Functioning - javascript

I'm trying to have an image slideshow with change captions on a home page I'm working on. I was using w3schools as the tutorial and I have it working on there, but when I put the code into my text editor nothing happens; nothing is rendering. I'm using Atom and running the code in its html preview screen and have the file open in my browser. I'm using external CSS and JavaScript files and using css-grid for the layout.
Here's my HTML:
<div class="slideshow-container">
<div class="mySlides fade">
<img src="headerpark.jpg" style="width:100%">
<div class="text">Caption One</div>
</div>
<div class="mySlides fade">
<img src="headerpark2.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<img src="headerpark3.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
</div>
My CSS:
.mySlides {display: none}
.slideshow-container {
grid-area: banner;
height: auto;
max-height: 100vh;
position: relative;
justify-self: stretch;
}
.slideshow-container img {
vertical-align: middle;
}
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
And lastly my JavaScript:
var slideIndex = 0;
showSlides(slideIndex);
function showSlides() {
var i;
var slides = document.getElementsByClassName("mySlides");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) {slideIndex = 1}
slides[slideIndex-1].style.display = "block";
setTimeout(showSlides, 5000);
}

Your code looks fine. Try copying it into an online IDE such as codepen.io and see if it works. It may just be your browser (emulator?).

It was trying to set block on the first slide before the slides collection existed, making sure slides is not undefined before calling that line fixes it.
var slideIndex = 0;
showSlides(slideIndex);
function showSlides() {
var i;
var slides = document.getElementsByClassName("mySlides");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
console.log(slideIndex);
slideIndex++;
if (slideIndex > slides.length) {slideIndex = 1}
if( typeof slides[slideIndex-1] !== 'undefined') {
slides[slideIndex-1].style.display = "block";
}
setTimeout(showSlides, 5000);
}
Now if you want to get a little fancier, this is a solution from a friend that creates a class so you can do things like instantiate it with options like time, or create a pause. Both solutions work with your code just by replacing the JS
class Slideshow {
constructor({delay = 5000, selector} = {}) {
this.delay = delay
this.index = 0
this.selector = selector
this.timeoutRef = undefined
}
play() {
console.log(this.index)
const slides = document.querySelectorAll('.mySlides')
slides.forEach(slide => slide.style.display = 'none')
slides.item(this.index).style.display = 'block'
this.index = this.index >= slides.length - 1 ? 0 : this.index + 1
this.timeoutRef = setTimeout(this.play.bind(this), this.delay)
}
}
const slideshow = new Slideshow({ selector: '.mySlides'})
slideshow.play()

Related

Javascript interfering with CSS Transition

I've recently started work on a basic landing-page website. Part of the page is a basic image slider with both the auto-nav and the manual nav being powered by JS. I got everything working but for one thing: I just can't figure out how to get the smooth transition between images - as seen in this example - to work. I figured out the problem after reading some related questions on Stackoverflow: To make the Slideshow work I'm using slides[i].style.display = "none"; and slides[slideIndex-1].style.display = "block"; to update the css code handling the 'display' element - this over rights the 'transition: 2s' css code one would need for the simple slide animation as seen in the video.
As I'm terribly new to Web development I could not wrap my head around possible solutions posted here on Stackoverflow and would really appreciate anyone that could help me out with an answer to my specific problem or an alternative way to solve it.
Cheers,
Jerome
var slideIndex = 1;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("item");
var dots = document.getElementsByClassName("dot");
if (n > slides.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className += " active";
}
//automatic
var slideIndexAuto = 0;
showSlidesAuto();
function showSlidesAuto() {
var i;
var slides = document.getElementsByClassName("item");
var dots = document.getElementsByClassName("dot");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
dots[i].className = dots[i].className.replace(" active", "");
}
slideIndexAuto++;
if (slideIndexAuto > slides.length) {
slideIndexAuto = 1
}
slides[slideIndexAuto - 1].style.display = "block";
dots[slideIndexAuto - 1].className += " active";
setTimeout(showSlidesAuto, 5000);
}
.slider {
width: 65%;
max-width: 940px;
height: 500px;
border-radius: 0.25rem;
position: relative;
overflow: hidden;
}
.slider .left-slide,
.slider .right-slide {
position: absolute;
height: 40px;
width: 40px;
background-color: #444444;
border-radius: 50%;
color: #ffffff;
font-size: 20px;
top: 50%;
cursor: pointer;
margin-top: -20px;
text-align: center;
line-height: 40px;
}
.slider .left-slide:hover,
.slider .right-slide:hover {
box-shadow: 0px 0px 10px black;
background-color: #29a8e2;
}
.slider .left-slide {
left: 30px;
}
.slider .right-slide {
right: 30px;
}
.slider .slider-items .item img {
width: 100%;
height: 500px;
display: block;
}
.slider .slider-items .item {
position: relative;
transition: 4s;
}
.slider .slider-items .item .caption {
position: absolute;
width: 100%;
height: 100%;
bottom: 0px;
left: 0px;
background-color: rgba(0, 0, 0, .5);
}
<div class="slider">
<div class="slider-items">
<div class="item fade">
<img src="/images/cs-slider-high.jpg" />
<div class="caption">
<p class="caption-text">COMING</p>
<p class="caption-text">OKTOBER 10th</p>
</div>
</div>
<div class="item fade">
<img src="/images/building-slider.jpg" />
<div class="caption">
<p class="caption-text-2">Blackstoneroad 109</br>
</p>
</div>
</div>
<div class="item fade">
<img src="/images/kontact-slider.jpg" />
<div class="caption">
<p class="caption-text-3">Coffee<br>Drinks<br>Food<br>& More</p>
</div>
</div>
<div class="item fade">
<img src="/images/seminar-slider.jpg" />
<div class="caption">
<p class="caption-text-3">Seminar Rooms<br>Inspiration<br>Shopping<br>& More</p>
</div>
</div>
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<!-- The dots/circles -->
<div class="align-text-center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
How is this: http://jsfiddle.net/lharby/qox05y96/
For simplification I have stripped out the dot animation (although that code is closer to the effect you want).
Here is the simplified JS:
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("item");
var dots = document.getElementsByClassName("dot");
if (n > slides.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].classList.remove('active'); // this is updated
}
slides[slideIndex - 1].className += " active";
}
//automatic
var slideIndexAuto = 0;
showSlidesAuto();
function showSlidesAuto() {
var i;
var slides = document.getElementsByClassName("item");
var dots = document.getElementsByClassName("dot");
for (i = 0; i < slides.length; i++) {
slides[i].classList.remove('active'); // this is updated
}
slideIndexAuto++;
if (slideIndexAuto > slides.length) {
slideIndexAuto = 1
}
slides[slideIndexAuto - 1].classList.add('active'); // this is updated
setTimeout(showSlidesAuto, 4000);
}
This means we also have to change the css. display none/block is harder to animate with css transitions. So I have used opacity: 0/1 and visibility: hidden/visible. However one other trade off is that that the item elements cannot be positioned relatively this would stack them on top of one another (or side by side) usually for an animated slideshow you would use position absolute for each slide, but I realise that causes you another issue.
CSS:
.slider .slider-items .item {
visibility: hidden;
opacity: 0;
transition: 4s;
}
.slider .slider-items .item.active {
visibility: visible;
opacity: 1;
transition: 4s;
}
At least now all of the css is handled within the css and the js purely adds or removes a class name which I feel makes it a bit easier to update.
There are priorities as far as what CSS deems should happen.
Take a look at this and let me know if it changes anything for you. If not I'll try and run the code and fix your errors. I want to let you know in advance, I am a pure JS developer. When I need CSS or HTML I create it in JS. I want you to try first, thus it will make you a better developer.
https://www.thebookdesigner.com/2017/02/styling-priorities-css-for-ebooks-3/

how to make my slider has responsive height

hello guys have been trying to make this slider has responsive height so it can fix perfectly on mobile but quite cant get it maybe you can help me here is my html
<div class="slideshow-container">
<div class="mySlides fade">
<img src="images/slider3.jpg" style="width:100%">
<div class="text">LET'S CAPTURE YOUR HAPPIEST MOMENTS</div>
</div>
<div class="mySlides fade">
<img src="images/slider4.jpg" style="width:100%">
<div class="text">EXPRESS YOURSELF!</div>
</div>
</div>
<div style="text-align:center">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
and the css
.mySlides {display: none;
}
img {vertical-align: middle;
}
/* Slideshow container */
.slideshow-container {
max-width: 1300px;
position: relative;
margin: auto;
}
the javascript
var slideIndex = 0;
showSlides();
function showSlides() {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) {slideIndex = 1}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
setTimeout(showSlides, 2000); // Change image every 2 seconds
}
please help me am going crazy i have tried editing the css by adding height:auto; to mySlides didnt work thanks
.slideshow-container{
width:50vw;
height:50vh
}
//vw and vh stretch with respect to screen size
//you can set limit of vw and vh as per you need

How to create divs for slideshow image change left/ right on click?

I am trying to create a div that is 50% width left and another 50% width right of the viewport. I want each div to change the slideshow image previous / next on click
Example: https://jonoverrall.com/colin/owzib05x14nq1xd08etgqoe7nmmvum
Does anyone have any suggestions on how to achieve this?
<div class="slideshow-container">
<div class="mySlides fade">
<img src="001%20(1).jpg" onclick="plusSlides(1)">
<div class="text">As a Fountain 2017</div>
<div class="opacity">001 </div>
</div>
<div class="mySlides fade">
<img src="001%20(2).jpg" onclick="plusSlides(1)">
<div class="text">Deliverance 2017</div>
<div class="opacity">002 </div>
</div>
CSS
img {
height: 100%;
width: 100%;
max-height: 100vh;
max-width: 100vh;
object-fit: contain;
}
.mySlides img {
display: inline-block;
vertical-align: middle;
}
.slideshow-container img {
display: block;
margin: 0px auto;
}
JS
var slideIndex = 1;
var indexes = document.querySelectorAll(".numbertext span");
var slides = document.getElementsByClassName("mySlides");
indexes[1].innerHTML = slides.length;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
if (n > slides.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = slides.length
}
indexes[0].innerHTML = slideIndex;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex - 1].style.display = "block";
}
https://codepen.io/anon/pen/xobQRM

Do not run CSS animation on first load

The first image should not fade in when the user loads the page. It should only fade in after the first and subsequent cycles are completed. I basically want the first image to fully appear right away on page load.
HTML:
<div class="slideshow-container">
<div class="mySlides fade">
<img src="VirtualBox_Fedora_12_11_2017_02_22_46.png">
</div>
<div class="mySlides fade">
<img src="25945941662_d9a450d7ef_b.jpg">
</div>
<div class="mySlides fade">
<img src="img3.jpg">
</div>
</div>
CSS:
.mySlides {
display: none;
}
.mySlides.fade img {
/*background: */
display: block;
height: 60vh;
margin: auto;
margin-bottom: 10px;
}
.fade {
animation-duration: 1.0s;
animation-name: fade;
}
#keyframes fade {
from {opacity: .6}
to {opacity: 1}
}
JS:
var slideIndex = 0;
showSlides();
function showSlides() {
var i;
var slides = document.getElementsByClassName("mySlides");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) {slideIndex = 1}
slides[slideIndex-1].style.display = "block";
setTimeout(showSlides, 5000); // Change image every 2 seconds
}
I believe using data attributes can be useful for enabling/disabling animations in general...
var slideIndex = 0
, slides = document.getElementsByClassName('mySlide');
slides[slideIndex].style.display = 'block';
setTimeout(showNextSlide, 5000);
function showNextSlide() {
var l = slides[slideIndex++];
l.dataset.dontAnimate = 0;
l.style.display = 'none';
if(slides.length == slideIndex)
slideIndex = 0;
slides[slideIndex].style.display = 'block';
setTimeout(showNextSlide, 5000);
}
.mySlide {
display: none;
}
.mySlide img {
display: block;
height: 60vh;
margin: auto;
margin-bottom: 10px;
}
.fade:not([data-dont-animate="1"]) {
animation-name: fade;
animation-duration: 1.0s;
}
#keyframes fade {
from { opacity: 0.6 }
to { opacity: 1 }
}
<div class="slideshow-container">
<div class="mySlide fade" data-dont-animate="1">
<h1>
Slide 1
</h1>
</div>
<div class="mySlide fade">
<h1>
Slide 2
</h1>
</div>
<div class="mySlide fade">
<h1>
Slide 3
</h1>
</div>
</div>
Add a class for which will exempt the first img from the animation. e.g.
.fade:not(.first) {
animation-duration: 1.0s;
animation-name: fade;
}
Just be sure to remove the class after the initial load. Using something like the following:
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
// the check
if (slides[i].classList.contains('first')) {
slides[i].classList.remove('first');
}
}
Here's a working example: https://codepen.io/pablo-tavarez/pen/JONKrW

Fadeout on slideshow using javascript

As the title states I want to add a fadeout animation once an image in my slideshow swaps only using html, css and javascript. I'm not quiet sure how to do this, but I have some idea. I was thinking I could add an id on the current image, like #fadeout so it gets specific characteristics when fadeing out.
var myIndex = 0;
window.onload = slidePictures();
function slidePictures() {
var i;
var slides = document.getElementsByClassName("mySlides");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
slides[i].setAttribute("id", "fadeout");
}
myIndex++;
if (myIndex > slides.length) {
myIndex = 1
}
slides[myIndex - 1].style.display = "block";
document.getElementById("indicator").innerHTML = myIndex + "/" + slides.length;
setTimeout(slidePictures, 3000);
}
.slidesDiv>img {
width: 80%;
height: 80%;
margin-left: 10%;
opacity: 1;
transition: opacity 1s;
}
#fadeOut {
opacity: 0;
}
<div class="slidesDiv">
<img class="mySlides" src="//placehold.it/200x80/0fb">
<img class="mySlides" src="//placehold.it/200x80/0bf">
<img class="mySlides" src="//placehold.it/200x80/fb0">
<img class="mySlides" src="//placehold.it/200x80/0fb">
<h1 id="indicator"> Indicator </h1>
</div>
You shouldn't you display property with transition, because it isn't animatable.
I recommend using position: absolute and hiding elements on init.
I think it's better to combine fade in/fade out effects.
Try this example:
var indexes = {current: 0};
var slides = document.getElementsByClassName('mySlides');
window.onload = slidePictures();
function slidePictures() {
if (indexes.last) {
slides[indexes.last].classList.remove('visible');
}
slides[indexes.current].classList.add('visible');
document.getElementById('indicator').innerHTML = (indexes.current + 1) + '/' + slides.length;
indexes.last = indexes.current;
indexes.current++;
if (indexes.current >= slides.length) {
indexes.current = 0;
}
setTimeout(slidePictures, 3000);
}
html, body {
width: 100%;
height: 100%;
}
.slidesDiv {
width: 80%;
height: 80%;
margin-left: 10%;
position: relative;
}
.mySlides {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: all 1s;
}
.visible {
opacity: 1;
}
<div class="slidesDiv">
<img class="mySlides" src="//placehold.it/200x80/0fb">
<img class="mySlides" src="//placehold.it/200x80/0bf">
<img class="mySlides" src="//placehold.it/200x80/fb0">
<img class="mySlides" src="//placehold.it/200x80/bbb">
</div>
<h1 id="indicator">1/4</h1>
JSFiddle
I recommend using style attributes only. If you want to use CSS for applying a new style a new CSS class may be better. Then you could use slide.className += 'fadeOut'; .
Now the code for fading images:
function fadeIn(element) { element.style['display'] = '';
element.style['opacity'] = 1; }
function fadeOut(element) {
element.style['opacity'] = 0;
setTimeout(function() { element.style['display'] = 'none'; }, YOUR_ANIMATION_DURATION_IN_MILLISECONDS);
}
function fadeBetween(from, to) {
fadeIn(from);
fadeOut(to);
}
That's the easiest I use to do it. Of course you could modify it to use CSS classes instead of style attributes. It should be easy to create a loop and cycle through all images which should be faded in our out.

Categories

Resources