I created a simple picture slideshow for my website but the problem I have is when you first go to the site it shows all the pictures and its not until you click one of the scroll arrows that it goes to a slideshow. I want it to automatically only show one picture at a time when you first open the website. Here is the code I have:
<div class="wrapper">
<h2>Gallery</h2>
<img class="mySlides" src="assets/images/chickens1.jpg">
<img class="mySlides" src="assets/images/goat1.jpg">
<img class="mySlides" src="assets/images/goat4.jpg">
<img class="mySlides" src="assets/images/goat2.jpg">
<button class="w3-button w3-display-left" onclick="plusDivs(-1)">❮</button>
<button class="w3-button w3-display-right" onclick="plusDivs(+1)">❯</button>
JavaScript:
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) { slideIndex = 1; }
if (n < 1) { slideIndex = x.length; }
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex-1].style.display = "block";
}
It's hard to tell just from what you've posted, but what I expect is going on is that initially, all 4 images are visible, due to the CSS styling on them. Then, when a user interacts with the page, your JavaScript gets called, which makes only 1 of them visible.
One thing you might try is to set it up so they are all set to display:none to begin with, and on page load, call showDivs(1).
Related
I have two images with different classes but I want the same JavaScript to be applied to both. This javascript basically allows for a slideshow by clicking on the button, but this only works for the images with the mySlides class, not the albums class. Take a look:
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.querySelectorAll(".mySlides, .albums");
if (n > x.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = x.length
};
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "block";
}
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet"/>
<div class="inner">
<img class="mySlides" src="./imgs/IMG_1552.JPG">
<img class="mySlides" src="./imgs/IMG_0915.jpg">
<button class="w3-button w3-display-left" onclick="plusDivs(-1)">❮</button>
<button class="w3-button w3-display-right" onclick="plusDivs(+1)">❯</button>
</div>
<div class="inner">
<img class="albums" src="./imgs/travis.jpg">
<img class="albums" src="./imgs/killy.jpg">
<button class="w3-button w3-display-left" onclick="plusDivs(-1)">❮</button>
<button class="w3-button w3-display-right" onclick="plusDivs(+1)">❯</button>
</div>
The buttons are supposed to move to the next image eg from "travis.jpg" to "killy.jpg" but it only works for the mySlides class and not the albums class
The issue lies in
var x = document.querySelectorAll(".mySlides, .albums");
As you have to understand that this query selects all the 4 elements if you want to do for the second element of both classes you would have to go with
var x = document.querySelectorAll(".mySlides");
var y = document.querySelectorAll(" .albums");
and run the further logic on both var seperately
I am looking to create multiple slideshows on a single page however it is currently not working
I understand that this question has been asked before but I can't seem to make those answers work with my code, does anyone have any suggestions? I don't have a huge amount of experience with Javascript
<div class="bareEditorial">
<div class="slideshow-container" onclick="plusSlides(1)">
<div class="mySlides fade">
<div class="image">
<img src="bareEditorialHero.jpg">
</div>
</div>
<div class="mySlides fade">
<div class="image">
<img src="bareEditorial2.jpg">
</div>
</div>
<div class="mySlides fade">
<div class="image">
<img src="bareEditorial3.jpg">
</div>
</div>
<div class="ninetydegrees">
<div class="nextprevious">
<div class="numbertext">Bare Boutique Editorial 2018 (<span>1</span> / <span>6</span>)</div>
</div>
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";
}
$(function() {
$('body').removeClass('fade-out');
});
Considering that you need information on implementing multiple slideshows on a page and not going into the detailed working for each, I'll suggest you to have a slideshow container with unique id for each slideshow and call your initialization method on each by passing the id as an argument.
Create a method as initializeSlideshow(containerID) and in that bind methods to for example next button as
function initializeSlideshow(containerID) {
$('#' + containerID + '.prevLink').on('click', function() {} );
//rest of your logic
}
Another approach would be to add a class to each container and implement the methods in a way that you capture the respective container using closest() and manipulate DOM
$('.containerClass .prevLink').on('click', function() {
$(this).closest('.containerClass').find('.slideCLass');
});
In an ideal scenario, one should write code to implement slideshow logic as a plugin where you can simply do
$('.slideshowContainer').initializeSlideshow( {
//slideshow options.
})
Which can be implemented as
$.fn.initializeSlideshow = function(slideshowOptions) {
//your logic where reference to this (object on which the method is called) is available
}
var myIndex = 0;
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {myIndex = 1}
x[myIndex-1].style.display = "block";
setTimeout(carousel, 2000); // Change image every 2 seconds
}
.mySlides {display:none;}
<body>
<h2 class="w3-center">Automatic Slideshow</h2>
<div class="w3-content w3-section" style="max-width:600px">
<img class="mySlides" src="cigand1.jpeg" style="width:30%">
<img class="mySlides" src="eu1.jpeg" style="width:30%">
<img class="mySlides" src="hun1.jpg" style="width:30%">
</div>
</body>
I think the code is right, but the third image is bigger in the slideshow than I want. I resized the image but does not work.
How to solve this problem? Did you meet problem like this? Now you can not see the pictures, the problem is other.
I am not sure but checking your code, you are just setting a max-width to the image.
<div class="w3-content w3-section" style="max-width:600px">
That means, if the picture width is less than 600px, (500px for instance) it will display a 500px width picture.
You can try something like this
<div class="w3-content w3-section" style="width:600px">
But the best way to do so, is to have all the pictures with the same width.
I put an image slider on my website to show the image one by one on click event, but on the last image I want to stop image slider. I don't want to repeat image again and I don't want forward slide but we can go back.
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) { slideIndex = 1 }
if (n < 1) { slideIndex = x.length }
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "block";
}
</script>
HTML:
<div class="w3-content w3-display-container">
<div style="margin-left:150px">
<img class="mySlides" src="../../../../../imageslider2/slide1.jpg" style="width:auto; height:auto"/>
<img class="mySlides" src="../../../../../imageslider2/slide2.jpg" style="width:auto; height:auto"/>
<pre> <a class="w3-btn-floating w3-display-left" onclick="plusDivs(-1)">❮</a>
<a class="w3-btn-floating w3-display-right" onclick="plusDivs(1)">❯</a>
</div>
First you need to get a count of the total number of slides and set it as a variable, which you can do with .length and then you need to add a conditional statement to your plusDivs function to do something(alert in the below example) if the slideIndex value is equal to that of the total number of slides:
var slideIndex = 1,
totalSlides = document.querySelectorAll('.mySlides').length;
showDivs(slideIndex);
function plusDivs(n) {
if (slideIndex === totalSlides) {
alert('End of slideshow');
} else {
showDivs(slideIndex += n);
}
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) { slideIndex = 1 }
if (n < 1) { slideIndex = x.length }
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "block";
}
<div class="w3-content w3-display-container">
<div style="margin-left:150px">
<img class="mySlides" src="http://placehold.it/250x250" style="width:auto; height:auto"/>
<img class="mySlides" src="http://placehold.it/250x250/000/fff" style="width:auto; height:auto"/>
<pre>❮
❯ </pre>
</div>
</div>
Alternatively, you could use the same approach to simply hide the previous or next buttons if they are at the start or the end of the slideshow.
I am looking to create an HTML color visualizer for steel buildings. This will be placed on my company's website. I'm wanting to see if it is possible (in HTML) to load image layers (in their fixed positions) onto a canvas background, after a visitor clicks on a color swatch.
Here is a similar solution I am seeking.
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = x.length
}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" w3-red", "");
}
x[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className += " w3-red";
}
.mySlides {
display: none
}
<button class="w3-button demo" onclick="currentDiv(2)">Tan Wall</button>
<button class="w3-button demo" onclick="currentDiv(3)">Red Roof</button>
<button class="w3-button demo" onclick="currentDiv(4)">Black Garage</button>
<button class="w3-button demo" onclick="currentDiv(5)">Black Trim</button>
<div class="w3-content" style="max-width:800px">
<img class="mySlides" src="http://metaldepotinc.com/Canvas-Background.png" style="width:100%">
<img class="mySlides" src="http://metaldepotinc.com/Wall-Tan.png" style="width:100%">
<img class="mySlides" src="http://metaldepotinc.com/Roof-Red.png" style="width:100%">
<img class="mySlides" src="http://metaldepotinc.com/Garage-Black.png" style="width:100%">
<img class="mySlides" src="http://metaldepotinc.com/Trim-Black.png" style="width:100%">
</div>
For example, when a visitor clicks on the "Red Roof" swatch I want the "Red-Roof.png" layer to load on top of the white building canvas. The positioning would be perfect since it is positioned correctly in the image file already. From there, I'd like the customer to add more image layers such as "Tan Wall" until the building combination fits their preferences. The final image should look like this after clicking all of the buttons.
Thanks for your time!
You can achieve this by css absolute positioning.
Additionally I recommend to use .classList.toggle instead of replacing the .className:
var slideIndex = 1;
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = x.length
}
x[slideIndex - 1].classList.toggle("active");
dots[slideIndex - 1].classList.toggle("w3-red")
}
.mySlides {
display: none;
position:absolute;
}
.mySlides.active{
display:block;
}
<button class="w3-button demo" onclick="currentDiv(1)">Tan Wall</button>
<button class="w3-button demo" onclick="currentDiv(2)">Red Roof</button>
<button class="w3-button demo" onclick="currentDiv(3)">Black Garage</button>
<button class="w3-button demo" onclick="currentDiv(4)">Black Trim</button>
<div class="w3-content" style="max-width:800px;position: relative;">
<img src="http://metaldepotinc.com/Canvas-Background.png" style="width:100%;position: absolute ;z-index:-1">
<img class="mySlides" src="http://metaldepotinc.com/Wall-Tan.png" style="width:100%">
<img class="mySlides" src="http://metaldepotinc.com/Roof-Red.png" style="width:100%">
<img class="mySlides" src="http://metaldepotinc.com/Garage-Black.png" style="width:100%">
<img class="mySlides" src="http://metaldepotinc.com/Trim-Black.png" style="width:100%">
</div>
EDIT:
According to the asker's comment...
Use absolute position on every image, and...
Use toggle buttons (checkbox behavior) instead of hiding all images on button click and showing only one (radio button behavior)