How to make images a simple slider in js - javascript

i only know html, js and css. i'm trying to make the images change every couple of seconds., as in a slideshow.
<script type="text/javascript">
var temp=1;
function slider(){
document.getElementById("pic1").style.display = 'none';
document.getElementById("pic2").style.display = 'none';
document.getElementById("pic3").style.display = 'none';
if(temp==1){
document.getElementById("pic1").style.display = 'block';
}
else if(temp==2){
document.getElementById("pic2").style.display = 'block';
}
else if (temp==3){
document.getElementById("pic3").style.display = 'block';
temp=1;
}
temp++;
setTimeout(slider(),25000);
}
</script>
the head is above, body below.
<div id="rightside" onload="slider()">
<a id="pic1"><img src="photos/hamilton/candyshop.jpg" style="display:block"></a>
<a id="pic2"><img src="photos/hamilton/hamiltonboat.jpg" style="display:none"></a>
<a id="pic3"><img src="photos/hamilton/waterduel.jpg" style="display:none"></a>
</div>

There are multiple errors in this that must all be fixed for it to work.
In the line setTimeout(slider(), 25000), you should pass slider, the function itself, not slider(), the return value of the function. Then you need to call slider() once after defining it to start the whole thing. You can do this in the JavaScript with document.addEventListener instead of the HTML with onload, making the HTML self-contained.
You set the img to display:none in the HTML, and then you set the element with ID pic1 to display: block. But this element isn’t the img, it’s the a. So you end up with a display: block <a> containing a display: none <img>, so nothing shows after all.
When you set temp = 1, immediately after that you run temp++, so picture #1 is never seen again. temp = 0 on that line would fix this, but it is better to make temp loop through “0, 1, 2” and use the modulo operator % that makes numbers loop if they are too high.
I also added alt attributes describing each of the images so the demo will work without the images loading. This would help your users too if they can’t see the images for whatever reason.
A working version:
document.addEventListener("DOMContentLoaded", function(event) {
var temp = 0;
function slider() {
document.getElementById("pic1").style.display = 'none';
document.getElementById("pic2").style.display = 'none';
document.getElementById("pic3").style.display = 'none';
if (temp == 0) {
document.getElementById("pic1").style.display = 'block';
} else if (temp == 1) {
document.getElementById("pic2").style.display = 'block';
} else if (temp == 2) {
document.getElementById("pic3").style.display = 'block';
}
temp = (temp + 1) % 3;
setTimeout(slider, 1500); // decreased delay for demo purposes
}
slider();
});
<div id="rightside">
<a id="pic1" style="display:block">
<img alt="candy shop" src="photos/hamilton/candyshop.jpg">
</a>
<a id="pic2" style="display:none">
<img alt="Hamilton boat" src="photos/hamilton/hamiltonboat.jpg">
</a>
<a id="pic3" style="display:none">
<img alt="water duel" src="photos/hamilton/waterduel.jpg">
</a>
</div>
After getting the code working like the above, you can also reduce the repetition by using loops and functions. With the following version, if you add more pictures, you will only need to change one line of code instead of copying and pasting multiple parts of your code. Splitting your code up into functions that are each simple has the additional benefit that the code is easier to understand and to check for errors in.
document.addEventListener("DOMContentLoaded", function(event) {
var currentIndex = 0;
var numPictures = 3;
function slideshow() {
hideAllPictures();
showPicture(currentIndex);
currentIndex = (currentIndex + 1) % numPictures;
setTimeout(slideshow, 1500);
}
function hideAllPictures() {
for (var i = 0; i < numPictures; i++) {
hidePicture(i);
}
}
function hidePicture(index) {
getPictureElement(index).style.display = 'none';
}
function showPicture(index) {
getPictureElement(index).style.display = 'block';
}
function getPictureElement(index) {
var id = "pic" + (index + 1);
return document.getElementById(id);
}
slideshow();
});
<div id="rightside">
<a id="pic1" style="display:block">
<img alt="candy shop" src="photos/hamilton/candyshop.jpg">
</a>
<a id="pic2" style="display:none">
<img alt="Hamilton boat" src="photos/hamilton/hamiltonboat.jpg">
</a>
<a id="pic3" style="display:none">
<img alt="water duel" src="photos/hamilton/waterduel.jpg">
</a>
</div>

Try this with Pure Javascript and CSS, change only myimage*.jpg to your image name.
<!DOCTYPE html>
<html>
<title>My Simple Slider</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.fading{
-webkit-animation:fading 10s infinite;
animation:fading 10s infinite
}
#-webkit-keyframes fading {
0%{opacity:0}
50%{opacity:1}
100%{opacity:0
}
}
#keyframes fading {
0%{opacity:0}
50%{opacity:1}
100%{opacity:0
}
}
</style>
<body>
<div>
<p>Simple Image Carousel</p>
<img class="mySlides fading" src="myimage1.jpg" style="width:100%">
<img class="mySlides fading" src="myimage2.jpg" style="width:100%">
<img class="mySlides fading" src="myimage3.jpg" style="width:100%">
<img class="mySlides fading" src="myimage4.jpg" style="width:100%">
</div>
<script>
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, 9000);
}
</script>
</body>
</html>

Related

How to get this button to fire the appropriate event

I am trying to get my slider interactive on a test i'm working on and I just can't figure it out. I have some code I have utilised from W3 but I'm trying to add a couple of events for the buttons so it is all on it's own javascript file instead of embedded in the HTML.
Here is the HTML:
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<script src="main.js" defer></script>
<body>
<h2 class="w3-center">Manual Slideshow</h2>
<div class="w3-content w3-display-container">
<img class="mySlides" src="./image_1.jpg" style="width:100%">
<img class="mySlides" src="./image_2.jpg" style="width:100%">
<img class="mySlides" src="./image_3.jpg" style="width:100%">
<button id="clicker" class="w3-button w3-black w3-display-left">❮</button>
<button id="clicker" class="w3-button w3-black w3-display-right">❯</button>
</div>
</body>
</html>
Here is the Javascript:
let leftSlideButton = document.getElementById("clicker");
let rightSlideButton = document.getElementById("clicker");
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";
}
let slideForward = plusDivs(1);
let slideBack = plusDivs(-1);
leftSlideButton.onclick = slideBack;
rightSlideButton.onclick = slideForward;
The slider worked when the script was embedded in the hmtl but when I tried to write in some functionality for the buttons in their own javascript file it just stops working and I'm pretty stumped now. Iv'e added them to their own variable and grabbed it's html selector so I can in turn add an event handler and link it to the function but it just doesn't work. Any help would be appreciated.
Also, this is my first post so apologies if I haven't formatted it correctly.
TIA, Neil.
Most likely the problem caused by 2 x id="clicker".
Using unique ids for the buttons should solve to problem.
Next, since slideIndex declared globally it doesn't require plusDivs middle-ware.
I would also suggest to use clearer functions and variables names for the sake of better readability. Check these: slideDivs vs showDivs, step vs n, slides vs x, etc. It maybe doesn't sound like a big deal on the given example, but it is a good habit and will save you a lot of time when working on bigger projects.
There are also some minor optimizations possible, such as changing visibility in one loop and caching slides outside of sliding function to avoid selecting it again on every click. Check the snipped for suggested rewritten code.
var visibleSlideIndex = 0;
var slides = document.getElementsByClassName("mySlides");
function slideDivs(step) {
visibleSlideIndex = (visibleSlideIndex + step + slides.length) % slides.length;
for (let index = 0; index < slides.length; index++) {
slides[index].style.display = visibleSlideIndex === index ? "block" : "none";
}
}
document.getElementById("slideLeftBtn").onclick = () => slideDivs(1);
document.getElementById("slideRightBtn").onclick = () => slideDivs(-1);
slideDivs(0);
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<script src="main.js" defer></script>
<body>
<h2 class="w3-center">Manual Slideshow</h2>
<div class="w3-content w3-display-container">
<img class="mySlides" src="./image_1.jpg" style="background-color: red;">
<img class="mySlides" src="./image_2.jpg" style="background-color: green;">
<img class="mySlides" src="./image_3.jpg" style="background-color: blue;">
<button id="slideLeftBtn" class="w3-button w3-black w3-display-left">❮</button>
<button id="slideRightBtn" class="w3-button w3-black w3-display-right">❯</button>
</div>
</body>
</html>
You have multiple issues :
First, the button selection. You are trying to get the 2 buttons with the same id, you have to change that.
Then, those 2 lines :
let slideForward = plusDivs(1);
let slideBack = plusDivs(-1);
plusDivs(1) and plusDivs(-1) are calling the function and returning the value. To fix it, you can create an anonymous function (or an arrow function) to call plusDivs
Here is a fixed version (I changed the width of the images to 25% so it would be easier to see in the snippet):
let leftSlideButton = document.getElementById("clickerLeft");
let rightSlideButton = document.getElementById("clickerRight");
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";
}
leftSlideButton.onclick = () => plusDivs(1);
rightSlideButton.onclick = () => plusDivs(-1);
<h2 class="w3-center">Manual Slideshow</h2>
<div class="w3-content w3-display-container">
<img class="mySlides" src="https://via.placeholder.com/150" style="width:25%">
<img class="mySlides" src="https://via.placeholder.com/200" style="width:25%">
<img class="mySlides" src="https://via.placeholder.com/250" style="width:25%">
<button id="clickerLeft" class="w3-button w3-black w3-display-left">❮</button>
<button id="clickerRight" class="w3-button w3-black w3-display-right">❯</button>
</div>
You can't have two identical ids, so I gave the buttons separate ids, then I attached an event listener to each one with addEventListener. Inside each listener I added the plusDivs() function directly in.
let leftSlideButton = document.getElementById("clicker-left");
let rightSlideButton = document.getElementById("clicker-right");
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";
}
leftSlideButton.addEventListener("click", () => {plusDivs(1)});
rightSlideButton.addEventListener("click", () => {plusDivs(-1)});
.w3-content > img{
max-height: 200px;
object-fit: contain;
background-color: lightblue;
}
<h2 class="w3-center">Manual Slideshow</h2>
<div class="w3-content w3-display-container">
<img class="mySlides" src="http://placekitten.com/100/200" style="width:100%">
<img class="mySlides" src="http://placekitten.com/200/200" style="width:100%">
<img class="mySlides" src="http://placekitten.com/150/200" style="width:100%">
<button id="clicker-left" class="w3-button w3-black w3-display-left">❮</button>
<button id="clicker-right" class="w3-button w3-black w3-display-right">❯</button>
</div>

Javascript Picture Slideshow

I'm using the basic code shown on https://www.w3schools.com/w3css/w3css_slideshow.asp to create an automatic slideshow for a website. Everything seems to be the same and for some reason, the slideshow is not working.
HTML:
<article id="elements">
<h2 class="major">Pictures</h2>
<div class="slideshow">
<script src="assets/slideshow.js"></script>
<img id="slide" src="images/colin1.jpg" style="width:75%">
<img id="slide" src="images/luke.jpg" style="width:75%">
<img id="slide" src="images/shep.jpg" style="width:75%">
</div>
CSS:
body #elements .slideshow #slide {
display: none;
}
JS:
var index = 0;
slideshow();
function slideshow() {
var i, x;
x = document.getElementById("slide");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
index++;
if (index > x.length) {
index = 1;
}
x[index-1].style.display = "block";
setTimeout(slideshow, 2000);
}
I appreciate anyone's help, and any ideas!
Agree with Gordon.
When selecting by ID only one element will be selected.
If you switch to using classes. e.g.
<img class="slide" src="images/colin1.jpg" style="width:75%">
Then you can select all the images using.
x = document.querySelectorAll(".slide");
which will return a nodeList, a similar construction to an Array but with different methods; that can be accessed via index. x[0], x[1], x[2].
hope this helps.
getElementById only returns one item, not an array, so you cannot use it to get all slides, use getElementsByClassName (https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName), and change id for classes:
var index = 0;
slideshow();
function slideshow() {
var i, x;
x = document.getElementsByClassName("slide");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
index++;
if (index > x.length) {
index = 1;
}
x[index - 1].style.display = "block";
setTimeout(slideshow, 2000);
console.log('changed image')
}
#elements .slideshow #slide {
display: none;
}
<article id="elements">
<h2 class="major">Pictures</h2>
<div class="slideshow">
<script src="assets/slideshow.js"></script>
<img class="slide" src="images/colin1.jpg" style="width:75%">
<img class="slide" src="images/luke.jpg" style="width:75%">
<img class="slide" src="images/shep.jpg" style="width:75%">
</div>
</article>

managing several show/hide divs

I have some scripts here that show and hide divs when click. Now what I need is to just only display one div at a time. I have a code that controls them all but its not working I don't know about much of javascript.
This is the first example of show/hide function that can be done simultaneously without hiding the other divs.
FIDDLE HERE
HTML:
<a href="javascript:ReverseDisplay('uniquename')">
Click to show/hide.
</a>
<div id="uniquename" style="display:none;">
<p>Content goes here.</p>
</div>
<a href="javascript:ReverseDisplay('uniquename1')">
Click to show/hide.
</a>
<div id="uniquename1" style="display:none;">
<p>Content goes here.</p>
</div>
SCRIPT:
function HideContent(d) {
document.getElementById(d).style.display = "none";
}
function ShowContent(d) {
document.getElementById(d).style.display = "block";
}
function ReverseDisplay(d) {
if (document.getElementById(d).style.display == "none") {
document.getElementById(d).style.display = "block";
} else {
document.getElementById(d).style.display = "none";
}
}
function HideAllShowOne(d) {
// Between the quotation marks, list the id values of each div.
var IDvaluesOfEachDiv = "idone idtwo uniquename1 uniquename";
//-------------------------------------------------------------
IDvaluesOfEachDiv = IDvaluesOfEachDiv.replace(/[,\s"']/g," ");
IDvaluesOfEachDiv = IDvaluesOfEachDiv.replace(/^\s*/,"");
IDvaluesOfEachDiv = IDvaluesOfEachDiv.replace(/\s*$/,"");
IDvaluesOfEachDiv = IDvaluesOfEachDiv.replace(/ +/g," ");
var IDlist = IDvaluesOfEachDiv.split(" ");
for(var i=0; i<IDlist.length; i++) { HideContent(IDlist[i]); }
ShowContent(d);
}
The other fiddle I created would do what I need but the script seems not to be working. Fiddle here
Found the solution on my code thanks to #Abhas Tandon
Fiddle here the extra id's inside the IDvaluesOfEachDiv seems to be making some error with the codes.
If you are happy with IE10+ support then
function ReverseDisplay(d) {
var els = document.querySelectorAll('.toggle.active:not(#' + d + ')');
for (var i = 0; i < els.length; i++) {
els[i].classList.remove('active');
}
document.getElementById(d).classList.toggle('active')
}
.toggle {
display: none;
}
.toggle.active {
display: block;
}
<a href="javascript:ReverseDisplay('uniquename')">
Click to show/hide.
</a>
<div id="uniquename" class="toggle">
<p>Content goes here.</p>
</div>
<a href="javascript:ReverseDisplay('uniquename1')">
Click to show/hide.
</a>
<div id="uniquename1" class="toggle">
<p>Content goes here.</p>
</div>
I would suggest to use jQuery which is far easier.
Include thiswithin
<head>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
</head>
HTML
<div id="id_one">Item 1</div>
<div id="content_one">
content goes here
</div>
<div id="id_two">Item 1</div>
<div id="content_two">
content goes here
</div>
Script:
$(function()
{
$("#content_one").hide();
$("#content_two").hide();
});
$("#id_one").on("click",function()
{
$("#content_one").slideDown("fast");
});
$("#id_two").on("click",function()
{
$("#content_two").slideDown("fast");
});
If you have a "Button" for every DIV inside your HTML - you can go by element index
var btn = document.querySelectorAll(".btn");
var div = document.querySelectorAll(".ele");
function toggleDivs() {
for(var i=0; i<btn.length; i++) {
var us = i===[].slice.call(btn).indexOf(this);
btn[i].tog = us ? this.tog^=1 : 0;
div[i].style.display = ["none","block"][us?[this.tog]:0];
}
}
for(var i=0; i<btn.length; i++) btn[i].addEventListener("click", toggleDivs);
.btn{/* Anchors Buttons */ display:block; cursor:pointer; color:#00f;}
.ele{/* Hidden Divs */ display:none;}
<a class="btn"> 1Click to show/hide.</a>
<div class="ele"><p>1Content goes here.</p></div>
<hr>
<a class="btn">2Click to show/hide.</a>
<div class="ele"><p>2Content goes here.</p></div>
<hr>

giving fideIn fadeOut effect on changing the image src

I was working with responsive web design and I wanted to slide some images in to a page. I tried some plugins but the problem with the plugin is it uses width and height property and also assigns position: absolute. So I thought of changing the src of the image myself using js and it worked fine, but can I give some transition effect to it?
Demo fiddle
What I have done is:
var i = 0;
var total = 2;
window.setInterval(function() {
show_hide();
}, 1000);
function show_hide() {
var img = $('.image-holder img, .image-holder2 img');
//alert(img.length);
if (i % 2 == 0) {
img[0].src = 'http://digimind.com/blog/wp-content/uploads/2012/02/number2c.png';
img[1].src = 'http://digimind.com/blog/wp-content/uploads/2012/02/number2c.png';
i = 0;
}
else {
img[0].src = 'http://healthystartups.com/storage/600px-MA_Route_1.png?__SQUARESPACE_CACHEVERSION=1319542839834';
img[1].src = 'http://healthystartups.com/storage/600px-MA_Route_1.png?__SQUARESPACE_CACHEVERSION=1319542839834';
}
i++;
}
My HTML is as follows:
<div class="image-holder" >
<img src="http://healthystartups.com/storage/600px-MA_Route_1.png?__SQUARESPACE_CACHEVERSION=1319542839834" />
</div>
<div class="image-holder2" >
<img src="http://healthystartups.com/storage/600px-MA_Route_1.png?__SQUARESPACE_CACHEVERSION=1319542839834" />
</div>
Here's what I put together. jsFiddle
javascript
var img = $(".image-holder img")
var i = 0;
var count = img.length - 1;
setInterval(function() {
showImage(i);
i++;
if (i > count) i = 0;
}, 2000);
function showImage(i) {
img.eq(i - 1).animate({
"opacity": "0"
}, 1000);
img.eq(i).animate({
"opacity": "1"
}, 1000);
}​
HTML
<div class="image-holder" >
<img src="http://healthystartups.com/storage/600px-MA_Route_1.png?__SQUARESPACE_CACHEVERSION=1319542839834" />
</div>
<div class="image-holder" >
<img src="http://digimind.com/blog/wp-content/uploads/2012/02/number2c.png" />
</div>​
CSS
.image-holder img{ opacity: 0;}
.image-holder { position: absolute; }

Show images one after one after some interval of time

I am new person in Front End Development and i am facing one major problem is that i have 3 images placed on each others and now i want to move one image so the other image comes up and then it goes and third image comes up after some interval of time.
I want three images on same position in my site but only wants to see these three images one after one after some interval of time.
Please help how i can do this??
May i use marquee property or javascript???
Non-jQuery Option
If you don't want to go down the jquery route, you can try http://www.menucool.com/javascript-image-slider. The setup is just as easy, you just have to make sure that your images are in a div with id of slider and that div has the same dimensions as one of your images.
jQuery Option
The jQuery cycle plugin will help you achieve this. It requires jquery to work but it doesn't need much setting up to create a simple sliple slideshow.
Have a look at the 'super basic' demo:
$(document).ready(function() {
$('.slideshow').cycle({
fx: 'fade' // choose your transition type, ex: fade, scrollUp, shuffle, etc...
});
});
It has many options if you want something a bit fancier.
Here you go PURE JavaScript solution:
EDIT I have added image rotation... Check out live example (link below)
<script>
var current = 0;
var rotator_obj = null;
var images_array = new Array();
images_array[0] = "rotator_1";
images_array[1] = "rotator_2";
images_array[2] = "rotator_3";
var rotate_them = setInterval(function(){rotating()},4000);
function rotating(){
rotator_obj = document.getElementById(images_array[current]);
if(current != 0) {
var rotator_obj_pass = document.getElementById(images_array[current-1]);
rotator_obj_pass.style.left = "-320px";
}
else {
rotator_obj.style.left = "-320px";
}
var slideit = setInterval(function(){change_position(rotator_obj)},30);
current++;
if (current == images_array.length+1) {
var rotator_obj_passed = document.getElementById(images_array[current-2]);
rotator_obj_passed.style.left = "-320px";
current = 0;
rotating();
}
}
function change_position(rotator_obj, type) {
var intleft = parseInt(rotator_obj.style.left);
if (intleft != 0) {
rotator_obj.style.left = intleft + 32 + "px";
}
else if (intleft == 0) {
clearInterval(slideit);
}
}
</script>
<style>
#rotate_outer {
position: absolute;
top: 50%;
left: 50%;
width: 320px;
height: 240px;
margin-top: -120px;
margin-left: -160px;
overflow: hidden;
}
#rotate_outer img {
position: absolute;
top: 0px;
left: 0px;
}
</style>
<html>
<head>
</head>
<body onload="rotating();">
<div id="rotate_outer">
<img src="0.jpg" id="rotator_1" style="left: -320px;" />
<img src="1.jpg" id="rotator_2" style="left: -320px;" />
<img src="2.jpg" id="rotator_3" style="left: -320px;" />
</div>
</body>
</html>
And a working example:
http://simplestudio.rs/yard/rotate/rotate.html
If you aim for good transition and effect, I suggest an image slider called "jqFancyTransitions"
<html>
<head>
<script type="text/javascript">
window.onload = function(){
window.displayImgCount = 0;
function cycleImage(){
if (displayImgCount !== 0) {
document.getElementById("img" + displayImgCount).style.display = "none";
}
displayImgCount = displayImgCount === 3 ? 1 : displayImgCount + 1;
document.getElementById("img" + displayImgCount).style.display = "block";
setTimeout(cycleImage, 1000);
}
cycleImage();
}
</script>
</head>
<body>
<img id="img1" src="./img1.png" style="display: none">
<img id="img2" src="./img2.png" style="display: none">
<img id="img3" src="./img3.png" style="display: none">
</body>
</html>​
Fiddle: http://jsfiddle.net/SReject/F7haV/
arrayImageSource= ["Image1","Image2","Image3"];
setInterval(cycle, 2000);
var count = 0;
function cycle()
{
image.src = arrayImageSource[count]
count = (count === 2) ? 0 : count + 1;
}​
Maybe something like this?

Categories

Resources