How to stop my images loading before the javascript slideshow loads? - javascript

I am new to this and have a quick question. I have a very simple slideshow on my home page. The problem I am having is the first second or so of loading the page, the slideshow images show up 1 on top of the other. Once the first second or so of loading the page is over, everything works fine. Here is my code for the javascript:
<script type="text/javascript" language="javascript">
window.onload = function () {
var rotator = document.getElementById("slideshow_content");
var images = rotator.getElementsByTagName("img");
for (var i = 1; i < images.length; i++) {
images[i].style.display = "none";
}
var counter = 1;
setInterval(function () {
for (var i = 0; i < images.length; i++) {
images[i].style.display = "none";
}
images[counter].style.display = "block";
counter++;
if (counter == images.length) {
counter = 0;
}
}, 3000);
};
</script>
Here is the body code:
<div id="slideshow">
<div id="slideshow_content" style="padding-top:10px; padding-bottom:10px;">
<img alt="" src="/images/slide1.jpg" />
<img alt="" src="/images/slide2.jpg" />
</div>
</div>
Here is the CSS for the 2 divs:
#slideshow {position:relative; top:0; left:0; max-width:1680px; height:342px; margin:0 auto; padding:0; background-color:#070707;}
#slideshow_content {width:960px; max-height:322px; margin:0 auto; padding:0;}
How would you recommend fixing this?

I would set the CSS to hide the slideshow on page load, and then when the slideshow starts it could be unhidden.
This would also mean that if someone had javascript disabled they wouldn't get a weird looking pile of images.
Alternatively you could hide all but the first image using CSS, so that even if someone had javascript disabled they would see the first image.

Related

adding a classList to each element at a time in a array - plain js

I'm new to javascript and I've been trying something that although basic i can't really seem to understand why it isn't working.
I have three images and one button. Everytime I click that same button i want one of the images to disappear (using classList to add a Css class of display: none).
I'm trying to use the for loop but when I click the button they disappear at the same time. I've tried to create a variable inside the loop to store the index value but it returns an error.
Help please !!! Thanks
\\ Js
window.onload = function(){
var button = document.querySelector("button");
var imgs = document.querySelectorAll("#imagens img");
button.addEventListener("click",function(){
for(var i=0; i<imgs.length; i++){
imgs[i].classList.add("hidden");
//var currentImg = this.imgs[i];
//currentImg.classList.add("hidden");
}
})
};
\\\ CSS
.hidden{
display:none;
}
#images{
width:400px;
height:200px;
margin:0 auto;
}
#images img{
width:110px;
height:100px;
}
button{
margin:100px auto;
}
\\\ HTML
<div id="images">
<img src="https://media.defense.gov/2018/Jul/11/2001941257/780/780/0/180711-F-EF974- 0115.JPG" alt="">
<img src="https://live.staticflickr.com/3267/2590079513_12e2c73226_b.jpg" alt="">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Poinsettia_tree.jpg/360px-Poinsettia_tree.jpg" alt="">
<div>
<button type="button">change</button>
</div>
</div>
You can use setTimeout for this requirement and update the for loop inside button click like:
for (var i = 0; i < imgs.length; i++) {
(function(index) {
setTimeout(function() {
imgs[index].classList.add("hidden");
}, i * 1500);
})(i);
}
This way hidden class would be added to one image at a time after a delay of 1500 ms.
The problem is that every time the button is clicked, you loop through all the images so you add to all of them the hidden class. What you need to do is to create a global variable that can store the index of the last image you hid.
And when you click the button, you add the hidden class to the image at the index + 1 then increment that index for the next image. You don't need to have a for loop for that.
You also mistyped in your query selector, it should be
var imgs = document.querySelectorAll("#images img");
instead of
var imgs = document.querySelectorAll("#imagens img");
So here's what you should have :
let index = -1;
window.onload = function(){
var button = document.querySelector("button");
var imgs = document.querySelectorAll("#images img");
button.addEventListener("click",function(){
index++;
imgs[index].classList.add("hidden");
})
};
.hidden {
display: none;
}
#images {
width: 400px;
height: 200px;
margin: 0 auto;
}
#images img {
width: 110px;
height: 100px;
}
button {
margin: 100px auto;
}
<div id="images">
<img src="https://media.defense.gov/2018/Jul/11/2001941257/780/780/0/180711-F-EF974- 0115.JPG" alt="">
<img src="https://live.staticflickr.com/3267/2590079513_12e2c73226_b.jpg" alt="">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Poinsettia_tree.jpg/360px-Poinsettia_tree.jpg" alt="">
<div>
<button type="button">change</button>
</div>
</div>

Javascript Slideshow Won't Show First Array Until the Button is Clicked

My slideshow works great except when the page loads initially. I've set my CSS to "display:none" to begin with, then the Javascript loops through the images to display them as inline-blocks when the next button is clicked. But, the first image displays as "none" to start out.
I'm sure there's a way to just display the first image while keeping all the images after hidden. I'm pretty new to this.
I followed along a tutorial on w3schools.com here: https://www.w3schools.com/howto/howto_js_slideshow.asp
You can see my full code and the product on my codepen:
https://codepen.io/catherinehh/pen/orpeJV
CSS:
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Hide the images by default */
.slideImg {
display: none;
}
JAVASCRIPT:
var slideIndex = 1;
function nextSlide(n){
showSlides(slideIndex += n);
}
function currentSlide(n){
showSlides(slideIndex = n);
}
function showSlides(n){
var i;
var slides = document.getElementsByClassName("slideImg");
if (n > slides.length){
slideIndex = 1;
}
if (n < 1){
slideIndex = slides.length;
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "inline-block";
}
I've basically followed the tutorial on w3schools.com line by line, and I can't find where my code differs from the tutorial. It should run just like the slideshow on that page.
Any help is appreciated! Thank you!
You have forgotten to initialize the slider by calling showSlides(slideIndex)
var slideIndex = 1;
function nextSlide(n){
showSlides(slideIndex += n);
}
function currentSlide(n){
showSlides(slideIndex = n);
}
function showSlides(n){
var i;
var slides = document.getElementsByClassName("slideImg");
if (n > slides.length){
slideIndex = 1;
}
if (n < 1){
slideIndex = slides.length;
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "inline-block";
}
showSlides(slideIndex)
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Hide the images by default */
.slideImg {
display: none;
}
<div class="wrapper">
<header>
<h1>Catherine Hill Hyman</h1>
<p>Professional Creations</p>
</header>
<main>
<section class="designSection">
<h2>Design</h2>
</section>
<section class="developmentSection">
<h2>Web Development</h2>
</section>
<section class="photoSection">
<h2>Photography</h2>
<!-- begin photo slideshow-->
<div class="photoSlideshow">
<button name="prevButt" onclick="nextSlide(-1)">❮</button>
<div class="slideImg">
<img id="uncleBud" src="https://scontent.fcae1-1.fna.fbcdn.net/v/t1.0-9/58378586_10157043937729774_1705977854832934912_n.jpg?_nc_cat=111&_nc_oc=AQl-LK_lpsqPa3rT2zTbc5KJpNNZECz9jxm15Xk0bNbYjtTklfxf34uVybG2xSjjffA&_nc_ht=scontent.fcae1-1.fna&oh=c5b64ef84d76c6d7ef2a9b9409e12637&oe=5DBFF07F"
alt="black and white image of half a woman's face with dark hair looming over the camera. Her eyes are not visible." style="height:300px">
</div>
<div class="slideImg">
<img src="https://scontent.fcae1-1.fna.fbcdn.net/v/t1.0-9/61008492_10157093314404774_1267282211523002368_o.jpg?_nc_cat=111&_nc_oc=AQldqecidxJd5LhQsCrYpnGnQ3mmLDqqMe9OGcChpmZyP82vSw7oBZvBDCZfbYktIGQ&_nc_ht=scontent.fcae1-1.fna&oh=c57a3d3827f6cab302470ec0e697f7ed&oe=5D88E446"
alt="black and white image of half a woman's face with dark hair looming over the camera. Her eyes are not visible." style="height:300px">
</div>
<div class="slideImg">
<img src="https://scontent.fcae1-1.fna.fbcdn.net/v/t1.0-9/59285770_10157043934564774_1801122100677705728_n.jpg?_nc_cat=107&_nc_oc=AQlfwDfzSUayQL0nmF9apZnwLzQJtIZw3KsWx2mM5P0O1x2q508-vo4lsCD6EfUD9ik&_nc_ht=scontent.fcae1-1.fna&oh=4948f8ea74480440b542e60d119e23a9&oe=5D7E8C45"
alt="black and white image of half a woman's face with dark hair looming over the camera. Her eyes are not visible." style="height:300px">
</div>
<button name="nextButt" onclick="nextSlide(1)">❯</button>
<script src="slideShow.js"></script>
</div>
<!-- end photo slideshow-->
</section>
<section class="writingSection">
<h2>Writing</h2>
</section>
</main>
If you want the slider to start working on page load, so you can call the first slide at the end of above codes:
showSlides(slideIndex);
For more confident (as I dont know where do you put the script in your page if in Header or after the Body tag) you can use <body onload="showSlides(1)"> to postpone the slider function after complete page load.
If you want to show the first image initially and start the slider on click, so use the CSS rule to exclude the first image of being hidden:
.slideImg:first-of-type {
display: block;
}

JavaScript - periodically change "active" image

I have 4 pictures and want them to periodically change class (I have .active class, which is similar to hover).
.active,
.pic:hover{
position: absolute;
border: 1px solid black;
transform: scale(1.1);
transition: transform .2s;
}
Basically I need the first picture to have the class active and after some time change it so the next picture has the class and the first one lose it.
Is something like that even possible?
Picture in HTML:
<div class="products">
<a href="http://example.com/produkt1">
<img class="pic" src="image.jpg" alt="image" width="75" height="75">
</a>
</div>
and JS:
productIndex = 0;
slideshow();
function slideshow(){
var i;
var pic = document.getElementsByClassName("pic");
for(i = 0; i < pic.length; i++){
pic[i].className = pic[i].className.replace("active", "");
}
productIndex++;
if(productIndex > pic.length){
productIndex = 1;
}
pic[productIndex-1].className += active;
setInterval(slideshow, 2000);
}
You can use setInterval to run a function periodically that will change the active class. Something like this (psuedo-code):
var imageArray = [];
var activeIndex = 0;
setInterval(function(){
imageArray[activeIndex].removeClass('active');
activeIndex++;
activeIndex %= 4;
imageArray[activeIndex].addClass('active');
}, 5000);
The number value passed in as a parameter is how many milliseconds to wait before running the function again. In this example, 5 seconds will pass between the classes are changed.
setInterval Reference
This is ugly but it could work for super basic ... You just need to update the div blocks with images if necessary. Uses jquery...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<style>
div {
width:50px;
height:50px;
background-color: black;
margin-bottom:10px;
}
.active {
background-color: red;
}
</style>
</head>
<body>
<div id="pic1"></div>
<div id="pic2"></div>
<div id="pic3"></div>
<div id="pic4"></div>
<script>
let lastActive = 0;
setInterval(()=>{
$('div').removeClass('active');
if(lastActive === 0){
$('#pic1').addClass('active');
lastActive = 1;
}
else if(lastActive === 1){
$('#pic2').addClass('active');
lastActive = 2;
}
else if(lastActive === 2){
$('#pic3').addClass('active');
lastActive = 3;
}
else if(lastActive === 3){
$('#pic3').addClass('active');
lastActive = 4;
}
else if(lastActive === 4){
$('#pic1').addClass('active');
lastActive = 1;
}
}, 500)
</script>
</body>
</html>
Matt L. has a good point here. Your code has the setInterval inside your slideshow function, otherwise it's fine.
productIndex = 0;
slideshow();
function slideshow(){
var i;
var pic = document.getElementsByClassName("pic");
for(i = 0; i < pic.length; i++){
pic[i].className = pic[i].className.replace("active", "");
}
productIndex++;
if(productIndex > pic.length){
productIndex = 1;
}
pic[productIndex-1].className += active;
}
setInterval(slideshow, 2000);
could probably work. Matt's answer is a lot better, and I came up with something similar, which is testable on jsfiddle.
You could do it like this for example:
$(document).ready(function() {
setInterval(function() {
var active = $('.active');
active.nextOrFirst().addClass('active');
active.removeClass('active');
}, 3000);
});
$.fn.nextOrFirst = function(selector)
{
var next = this.next(selector);
return (next.length) ? next : this.prevAll(selector).last();
};
.active,
.pic:hover{
border: 1px solid black;
}
.pic {
width: 150px;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image-container">
<img class="pic active" src="https://via.placeholder.com/350x150">
<img class="pic" src="https://via.placeholder.com/350x150">
<img class="pic" src="https://via.placeholder.com/350x150">
<img class="pic" src="https://via.placeholder.com/350x150">
</div>
Edit:
This, instead of most other solutions, will work with any amount of items. To use it only on pictures just specify via selector in the function.
Checkout this working example. I've made use of a combination of setInterval and setTimeout.
$(window).ready(()=>{
// get all the images inside the image-container div
let $images = $('.image-container').find('.image');
let currImage = 0;
// execute this code every 2 seconds
window.setInterval(()=>{
// add the active class to the current image
$($images[currImage]).addClass('active');
setTimeout(()=>{
// execute the code here after 1.5 seconds
// remove the active class from the previous image
$($images[currImage-1]).removeClass('active');
}, 1500);
// make sure we don't go over the number of elements in the collection
currImage = currImage >= $images.length ? 0 : currImage + 1;
}, 2000);
});
.image.active {
border: thin solid blue;
}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<div class="image-container" class="">
<img src="https://via.placeholder.com/200x200" class="image active">
<img src="https://via.placeholder.com/200x200" class="image">
<img src="https://via.placeholder.com/200x200" class="image">
<img src="https://via.placeholder.com/200x200" class="image">
</div>
Do make sure that the code in setTimeout will execute before the next interval. Meaning, the time set for setTimeout is always less than setInterval's :)
Yes it is possible:
function carousel() {
var images = document.querySelectorAll(".container img");
for(var i = 0; i < images.length; i++) {
if(images[i].classList.contains("active")) {
images[i].classList.remove("active");
if(i == images.length - 1) {
images[0].classList.add("active");
} else {
images[i + 1].classList.add("active");
}
break;
}
}
}
setInterval(carousel,1000);
img {
width: 100px;
margin-left: 10px;
transition: .2s;
}
.active {
transform: scale(1.1);
}
<div class="container">
<img src="https://i.stack.imgur.com/cb20A.png" class="active"/>
<img src="https://i.stack.imgur.com/cb20A.png"/>
<img src="https://i.stack.imgur.com/cb20A.png"/>
<img src="https://i.stack.imgur.com/cb20A.png"/>
</div>
You can then replace the .active class by whatever you want.

JS Slideshow with Next button

I want my code to act like a slideshow. If I click the next button it will hide the previous image and show the other image. It will show the first image, but it doesn't' go through the loop . I also have an error that say
"Uncaught TypeError: Cannot read property 'style' of undefined".
<!DOCTYPE html>
<html lang ="en">
<head>
<title> VIS</title>
<meta charset="utf-8"/>
</head>
<body>
<div style="position: relative; visibility: hidden;">
<img src="http://vignette4.wikia.nocookie.net/mrmen/images/5/52/Small.gif/revision/latest?cb=20100731114437"
alt="Pumpkins" id="Pum"/>
</div>
<div style="position: relative; visibility: hidden;">
<img src="http://vignette4.wikia.nocookie.net/mrmen/images/5/52/Small.gif/revision/latest?cb=20100731114437"
alt="Pumpkins" id="Straw"/>
</div>
<div style="position: relative; visibility: hidden;">
<img src="http://vignette4.wikia.nocookie.net/mrmen/images/5/52/Small.gif/revision/latest?cb=20100731114437"
alt="Pumpkins" id="Ras"/>
</div>
<button onclick="removeVisibility()">Next</button>
</body>
<script type="text/javascript" >
function removeVisibility(){
var imgs=document.getElementsByTagName('img');//get all the images
for(var i=0;i< imgs.length;i++){
imgs[i].style.visibility= 'visible'; //hide them
imgs[i-1].style.visibility= 'hidden';
}
}
</script>
</html>
jsBin demo
You have your DIV (!!!) elements set to visibility: hidden; but you're trying desperately to change the visibility to IMG.
Now that you know your main issue, you should better go with display none/block if you use position:relative (or rather use position: absolute for your overlaying elements...) Any way,
don't use inline CSS styles! That's why we invented stylesheets!
don't use inline JS! Use addEventListener to attach any desired event to your elements. Don't mix your application logic with (view) teplating.
var imagesHolder = document.getElementById("imagesHolder");
var images = imagesHolder.getElementsByTagName('img');
var imagesTot = images.length;
var button = document.getElementById("nextImage");
var counter = 0; // We'll use it to get the image index
function showNext(){
counter = ++counter % imagesTot; // Increment and loop counter
for(var i=0; i<imagesTot; i++){
if(i != counter) images[i].style.display = "none"; // Hide all but `counter` one
}
// Finally show the 'counter' one!
images[counter].style.display = "block";
}
button.addEventListener("click", showNext);
#imagesHolder img+img{ /* SHOW ALL BUT FIRST!*/
display:none;
}
<div id="imagesHolder">
<img src="http://lorempixel.com/400/200/sports/1" alt="1"/>
<img src="http://lorempixel.com/400/200/sports/2" alt="2"/>
<img src="http://lorempixel.com/400/200/sports/3" alt="3"/>
</div>
<button id="nextImage">Next</button>
...but wait!
Welcome to the world of responsive web design!
so let's add some animations and responsiveness:
var imagesHolder = document.getElementById("imagesHolder"),
images = imagesHolder.getElementsByTagName('div'),
n = images.length,
c = 0;
function showNext(){
c = ++c % n;
for(var i=0; i<n; i++) images[i].classList[i!=c?"add":"remove"]("fadeaway");
}
document.getElementById("nextImage").addEventListener("click", showNext);
showNext(); // Initial kick
*{margin:0;}
html, body{height:100%;}
#imagesHolder{
position:relative;
overflow:hidden;
width:100%;
height:90vh;
}
#imagesHolder div{
position: absolute;
width:inherit;
height:inherit;
background:50% / cover;
transition: 1s 0s ease;
/* Default when visible: */
opacity: 1;
transform: scale(1);
}
#imagesHolder div.fadeaway{
opacity:0;
transform: scale(1.2);
}
<div id="imagesHolder">
<div style="background-image:url(http://lorempixel.com/400/200/sports/1);"></div>
<div style="background-image:url(http://lorempixel.com/400/200/sports/2);"></div>
<div style="background-image:url(http://lorempixel.com/400/200/sports/3);"></div>
</div>
<button id="nextImage">Next</button>

Make a book reader using images [jquery]

I've been trying for the past hours to create a Comic Book online reader to allow my images to load up.
Everything works fine but I use a counter using a increment method basically and it just doesn't work because bringing down the increments breaks the function.
Maybe there is a simpler way? Also jQuery is the most obscure language to learn unlike HTML or PHP, jQuery has a documentation that pretty much has no organization. Its like here's all the stuff now read each one and maybe you'll find yours. My code is below
<script>
$(function manga () {
var count = 0;
var images = ["source_images/01.jpg", "source_images/02.jpg", "source_images/03.jpg", "source_images/04.jpg", "source_images/05.jpg", "source_images/06.jpg", "source_images/07.jpg"];
$("#left").click(function () {
var img = images[count % images.length];
++count;
$("#manga").attr("src", img);
//alert("clicked");
manga();
});
$("#right").click(function () {
var img = images[count % images.length];
--count;
$("#manga").attr("src", img);
//alert("clicked");
manga();
});
manga();
});
</script>
<title></title>
<center>
<img id="left" style="width:10%; float:left; padding:1.3%" src="files/left_arrow.png" />
<div >
<img id="manga" style="width:75%; float:left" src="source_images/00.jpg" />
</div>
<img id="right" style="width:10%; float:left; padding:1.2%" src="files/right_arrow.png" />
</center>
Basically your calling your function manga 3 times
first when it loads
second when your do left click
and third when you do right click
In this your initializing counter to keep track of the images and everytime
your calling function again your initializing it to 0
so your count again starting from 0.
So to avoid it make your count variable global declare it outside the manga() function.
checkout this code
<script>
var count = 0;
$(function manga () {
var images = ["source_images/01.jpg", "source_images/02.jpg", "source_images/03.jpg", "source_images/04.jpg", "source_images/05.jpg", "source_images/06.jpg", "source_images/07.jpg"];
$("#left").click(function () {
++count;
var img = images[count % images.length];
alert(img);
$("#manga").attr("src", img);
//alert("clicked");
manga();
});
$("#right").click(function () {
if(count == 0)
{
count = images.length-1;
}
else {
--count;
}
var img = images[count % images.length];
alert(img);
$("#manga").attr("src", img);
//alert("clicked");
manga();
});
manga();
});
</head>
<body>
<center>
<center>
<img id="left" style="width:10%; float:left; padding:1.3%" src="files/left_arrow.png" />
<div >
<img id="manga" style="width:75%; float:left" src="source_images/00.jpg" />
</div>
<img id="right" style="width:10%; float:left; padding:1.2%" src="files/right_arrow.png" />
</center>
</center>
I changed the position of count variable in both left and right click. And added one if condition in left click so that when the page loads first time and if user click left arrow first it will show last image.
so image src will move from first to last.It will work.

Categories