Image Carousel with Vanilla Javascript!

Let's face it. We're in an era of programming that relies heavily on libraries and frameworks.JQuery is a powerful, flexible and simplified way of writing JavaScript. JQuery for any of you who don't already know is a JavaScript library that condenses a lot of JavaScript functions and puts them in wrappers. Here's an example of the difference in JavaScript versus JQuery.

<div id="myDiv">
  <p class="text"></p>
  <p class="text"></p>
  <p class="textTwo"></p>
  <p class="text"></p>
</div>

<script>
//JAVASCRIPT

  var myDiv = document.getElementById("myDiv");

//jQuery

  var myDiv = $("#myDiv);

//JavaScript
  //Let's change the color of some lines of text
   
  var text = document.getElementsByClassName("text);
  var i;
  
  for(i = 0; i < text.length; i++) {
      d[i].className += " changeColor";
  }
//jQuery
   
   $(".text").addClass("changeColor");

</script>

Ok, so this simplifies things right? As you can see in that second example, what took us several lines of code was achievable through jQuery with just 1!. This doesn't make raw JavaScript bad, but it does make it more time consuming to write. But..what if you wanted to create a project in raw JavaScript, or maybe your employer doesn't want to use JQuery? It's always advisable to learn raw JavaScript BEFORE learning a library or framework so you know what's going on in the background when using a library.

So, I thought it would be fun to create an image carousel in raw JavaScript and see what we can do with it! Let's get started.

Files: Create our File Structure

  • slider.html
  • slider.css
  • slider.js 

 

These are the images that I used in the slider. Feel free to use these links as your images or choose your own. Size will not matter too much as we will be setting a max size to our images so they display properly

Images: Sample images to use in our slides.

  1. https://cdn.pixabay.com/photo/2015/12/01/20/28/road-1072823_1280.jpg
  2. https://cdn.pixabay.com/photo/2017/02/01/22/02/mountain-landscape-2031539_1280.jpg
  3. https://cdn.pixabay.com/photo/2020/01/04/23/37/landscape-4742004_1280.jpg

 

Important Elements that we will Create

  •  #carouselContainer - The main container that will hold all slider components
  • .mySlide - The individual slide containers that will hold all elements of each slide
  • .inner - The inner container of the slides. It will only hold the images
  • .dots-container - The container for the dots that will toggle between images
  • .dots - The individual dot elements
  • .arrows-container - The container to hold our next and previous arrows
  • .arrows - The left and right arrows

Functions we will be creating

  • params() - This function will hold our custom paramaters that we can pass custom params in such as showing or hiding our captions, dots and changing animations.
  • setParams() - We will use this to create a new params() object and write some conditional statements based on our current params.
  • changeSlides() - Function will will toggle slides when we click on the arrows to go forward or backward or our dots to get the current slide.
  • currSlide() - Get our current slide function
  • showSlides() - Hides all slides that except the active slide.
  • pause() - Pause our slider
  • resume() - Resume our slider

Now that we have our file structure and our images ready to go, let's start writing some code.

Step 1:Create our HTML markup.

<!DOCTYPE HTML>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0";>
      <title>Image Carousel</title>
        <script src="https://kit.fontawesome.com/5f0a34444a.js" crossorigin="anonymous"></script>
        <link type="text/css" href="/slider.css" rel="stylesheet"> 
   </head>

<body>

<div id="carouselContainer">
  
    <div class="mySlide fade">
     
      <div class="text">1/3</div>
       <div class="inner">
           <img class="slider" src="https://cdn.pixabay.com/photo/2015/12/01/20/28/road-1072823_1280.jpg" alt="test1"> 
       
      </div>
       <div class="caption">Country Trail in Autumn</div>
    </div>

    <div class="mySlide fade ">
        <div class="text">2/3</div>
          <div class="inner">
           <img class="slider" src="https://cdn.pixabay.com/photo/2017/02/01/22/02/mountain-landscape-2031539_1280.jpg" alt="test2"> 
        
      </div>
      <div class="caption">Path into the Misty Mountains</div>
    </div>

    <div class="mySlide fade">
        <div class="text">3/3</div>
          <div class="inner">
           <img class="slider" src="https://cdn.pixabay.com/photo/2020/01/04/23/37/landscape-4742004_1280.jpg" alt="test3"> 
           
        
      </div>
      <div class="caption">Beautiful Icy Lake with Snow Covered Trees</div>
    </div>

    <div class="dots-container">
         <span class="dots" onclick="currSlide(1)"></span>
         <span class="dots" onclick="currSlide(2)"></span>
         <span class="dots" onclick="currSlide(3)"></span>
    </div>
    
    <div class="arrows-container">
        <div class="arrows" id="next" onclick='changeSlides(1)'><i class="fas fa-chevron-right"></i></div>
        <div class="arrows" id="prev" onclick='changeSlides(-1)'><i class="fas fa-chevron-left"></i></div>
    </div>
    
</div>



<script type="text/javascript" src="/slider.js"></script>
 
  
  
</body>
</html>

If you put this code into a file and display it in your web browser, it wont look like much. Let's add a little CSS styling so we can see what we have to work with.

First, target the main carousel container and add center it up and give it a max width and set a height.

#carouselContainer {
    margin:0 auto;
    max-width:1000px;
    z-index:1
}

img {
    position:relative;
    max-width: 100%;
    border: 0;
    -ms-interpolation-mode: bicubic;
}

This should give you your three images stacked on top of each other. What we did was center the #carouselContainer and give it a max with of 1000px. This will make it responsive and adjust to the screen width. We also set the max-width of our images to be 100%.

Let's make a little magic happen with a little bit of JavaScript. 

var carousel = document.getElementById("carouselContainer");  // Select our carousel container and set it to a variable.
var slides = document.getElementsByClassName("mySlide");  // Get all elements with the class .mySlide
var img = document.querySelector(".slider");
var dotNav = document.getElementsByClassName("dots"); // Get all elements with the class name of .dots.
var i;
var timeOut; //Will store our Interval timer
var slideIndex = 1;  // Set our first image index to 1


showSlides = (n) => {  // Create our function to show the slide based on the current slide index. We will be passing in an argument later on when we create our next and previous buttons so we can skip or go back on our index.
 
  if (n > slides.length) {  // If our index goes over the amount of images we have, go back to the first index.
    slideIndex = 1;
  }
  if (n < 1) {
    slideIndex = slides.length;   // If our index goes under 1, go to the last image.

  }

  for (i = 0; i < slides.length; i++) {   // Hide all of our images
    slides[i].style.display = "none";
  }

  for (i = 0; i < dotNav.length; i++) {
    dotNav[i].className = dotNav[i].className.replace(" active", ""); // Remove the .active class from all dots that have the class assigned
  }

  slides[slideIndex - 1].style.display = "block";  // Display the slide with the current slide index. 
  
  dotNav[slideIndex - 1].className += " active";  // Add the .active class to the dot with the current slideIndex
    
 console.log(slides);    // send our slides to the console and you should see an array of elements with indexes of 0, 1, 2. Our slide Indexes go from 1, 2, 3. This is why we wrote slides[slideIndex - 1] so we can subtract one from our current index which will display the approriate index in our slides array.

}
showSlides();

This is what your slides array should look like in the console.

HTMLCollection(3) [div.mySlide.fade, div.mySlide.fade, div.mySlide.fade]
length: 3
0: div.mySlide.fade
1: div.mySlide.fade
2: div.mySlide.fade
__proto__: HTMLCollection

What we have done so far is set our slideIndex to a default of 1. That way when our slider is rotating, it will have a default index to fall back on for the first slide. Then if our index goes higher than the length of our slides array, which in our case is 3, we set our slideIndex back to 1. Then if our index goes to less than 1, which it will try to when set up our previous button, we don't want it to go under 1, so we set our slide index back to slides.length which in our case will be 3, or the last slide. 

Then we created a for loop which cycles through our slides array and sets each one to display = "none" by default. We need one slide to be shown at a time so we write slides[slideIndex -1].style.display = "block" which takes our slideIndex and subtracts 1 from it and uses that number to select the index of our slides array. For example, if our slideIndex is 2 and subtract 1, that means the code would look like slides[1].style.display = "block". Since the slides array begins with an index of `0`, we will be returning the 2nd slide which is what we want.

Now, let's add some styling to our .dots class so we have our selectors to select an individual image. We're going to position our .dots-container with absolute positioning and align it to the bottom and give it a width of 100% and center our content. For our .dots class, we are going to give them a little margin and a width of 40px and height of 10px; Let's also make the .active class so we can change the styling the dot with the current slideIndex.

.dots-container {
    position:absolute;   //Set it to absolute to we can align it to the bottom
    width:100%;          //Set the container to the full width of the slider
    bottom:0;            //Align the container to the bottom of the sldier
    text-align:center;   //Center our dots
}
.dots {
    cursor:pointer;      //Cursor will change to the pointer when hovered
    position: relative;    //Position the dots relative to the container
    display: inline-block;  // Display our dots next to eachother
    bottom: -30px;          // Move our dots slightly downward with a negative margin
    width: 40px;            
    text-align: center;
    height: 10px;
    background: #3084ff;
}

.active {
  background:#444;
}

You can style them however you wish, but so far you should have 3 rectangles at the bottom of the slider.  Now we need to toggle between images with our .dot selectors. If you notice in our html markup, our .dots element has an onclick="currSlide(1)" assigned to it with an index number being passed in as an argument. We need to create this function so when we click on our dots, or I guess in our case our rectangles, we call our currSlide() function and pass in the index number that that specific dot represents.

currSlide = (n) => {
  clearInterval(timeOut);
  showSlides(slideIndex = n);
}

Cool! Now we can manually toggle between images. If it's not working, go back and review the code and make sure there isn't anything you're missing. 

It looks like the slider changes height a bit each time we toggle through the images. Let's add some CSS to help this. We need to target our .inner class and give it a max-height and add overflow:hidden to hide the contents that go outside of the div. We will also by default set our slides to display:none.

.mySlide {
  display: none;

}

.inner {
  max-height:500px;
  overflow:hidden;
  z-index:999;
  
}

Great! Let's make our arrows look better. We need to target the .arrows class and give them some height and width. We also want set them to position:absolute and center them up using top:50% and transform:translateY(-50%).

.arrows {
    cursor:pointer;
    height:60px;
    width:36px;
    position:absolute;
    top:50%;
    transform:translateY(-50%);
    text-align:center;
    color:#444;
    background:#000;
    border-radius:5px 5px 5px 5px;
  
}
#prev{

    left:10px;
   
}

#next{
    
    right:10px;
   
}

I'm using font awesome for the arrows so if you want to use the same thing, you'll need to link font awesome in your script. I added a bit of styling to center up our arrows and make them a little more visible.

i {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    font-size: 30px;
    right: 7px;  
    color:#fff;
}

Awesome! That looks better. Let's add some styling to our captions now. 

.caption {
    position:absolute;
    bottom:0;
    width:100%;
    min-height:50px;
    height:auto;
    box-sizing:border-box;
    padding:10px;
    background:#000000a1;
    font-size:22px;
    color:#fff;
    text-align:center;
}

Looking good! When we click on the arrows, we should get an error in our console that says changeSlides is not defined. Let's define it! We need to create this function in our JavaScript file so we can skip slides and go back. Look back on our Html and find our #prev and #next arrows. We have an onclick='changeSlides(1) and onclick='changeSlides(-1).  The numbers that we are passing in as arguments will represent `n` in our function and determine if we advance a slide or go back.

changeSlides = (n) => {
  clearInterval(timeOut);   //Clear our current interval timer
    
  if (n < 0) {
    showSlides(slideIndex -= 1);  // if we click the previous button, we subtract 1 from slideIndex
  } else {
    showSlides(slideIndex += 1);  // if we click next, we add 1 to our slideIndex
  }
 
   timeOut = setInterval(function() {  //Set new interval. Call our changeSlides function to be greater than zero so we add one to our slideIndex. This will restart our slider.
      changeSlides(n + 2);
    }, 4000);
  
}

Now when we load our slider and we click on our arrows, we are able to go forward and backward on our slides. The images will rotate on a 4 second interval automatically now. But what about when the slide first loads? It doesn't automatically slide unless we click a dot or an arrow. That's because no interval has been set except for in our changeSlides function, so we need to automatically call our showSlides(slideIndex) function and pass in our slideIndex variable so the slider knows what slide to start off with. Then we need to assign our timeOut variable to a setInterval and call our changeSlides(slideIndex) function. Since our slideIndex starts at 1, it will tell the changeSlides() function to go to the next slide by increasing slideIndex by 1. How do we do this? Let's add an event listener on page load so we can call all of this logic when the slider loads.

window.addEventListener("load", function() {

    showSlides(slideIndex);    
  
    timeOut = setInterval(function() {

    changeSlides(slideIndex);

     }, 4000);

});

Now let's add some parameters to our slider where we can determine if we want to show or hide our dots, captions or animation or even change animation. We are going to create a simple JSON object to hold our values.

var params = {
    dots:true, //Change to "false" to remove nav dots under images
    caption:false,  //Change to "false" to remove captions on images
    fade:true // Change to "false" to remove animation
}

We're passing in dots, caption and fade as our parameters, because those are what we want to be able to manipulate. We will be making a simple fade animation, but if you would like to create others, you can make new animations and pass them into the params. Lets make our setParams() function that will set the parameters based on conditions.

setParams = () => {

  if (params.caption != true) {   //If captions are not set to true, remove them
    var cap = document.querySelectorAll(".caption");
    for (let i = 0; i < cap.length; i++) {
      cap[i].className += " remove";
    }
  }
  if (params.dots != true) {   //If dots are not set to true, remove them
    let dots = document.querySelectorAll(".dots");
    for (let i = 0; i < dots.length; i++) {
      dots[i].className += " remove";
    }
  }
  if (params.fade != true) {   //If fade is not set to true, remove them
    for (let i = 0; i < slides.length; i++) {
      slides[i].className = "mySlide";
    }
  }
}

You'll also have to add this class to your CSS file 

.remove {
  display:none !important;
}

Try changing the values in our params variable to false and see if the captions and dots dissapear! All we need to do now is add our fade animation to our CSS file. I'm not going to cover animation much in here, but what we're doing is creating a class called fade. We are going to make the animation called fade and set it to a duration of 4 seconds, which is the same as the interval of our slides. If we change the interval, we need to change the duration of the animation as well. Then we create our @keyframes fade which we will give it several values of opacity. The slider will fade in slightly on page load, and then fade back out after a couple of seconds. 

.fade {
  animation-name:fade;  //Create animation name
  animation-duration:4s; // Set duration
  
}

@keyframes fade {      //Create our keyframes to have opacity change at different percentages. The percentages are relative to the length of the animation. Example, 50% is 2 seconds into our animation since we have a 4 second duration.
  0%  { opacity:.06; }
  30% { opacity : 1; }
  50% { opacity : 1; }
  70% { opacity : 1; }
  100% { opacity : .06; }
  
}

Well done! That's cool! You can do more research on CSS animation and try to come up with some others that you can implement with the slider. Depending on  the animation, you may have to adjust a bit of code here and there to make it work, but see what you can do!

Last but not least, let's create a pause() and resume() function so when we hover over the slider it will pause, and when we take the mouse off, the slider will resume. To do this, we need to first clear our interval to pause our slider, then to resume, we clear our interval again and set our timeOut variable to a new interval and call our changeSlides(slideIndex) function while passing in our slideIndex as an argument.

 

resume = () => {
  clearInterval(timeOut);
  timeOut = setInterval(function() {
    changeSlides(slideIndex);
  }, 4000);
};

pause = () => {
  clearInterval(timeOut);

};

BONUS! Awesome Box Shadow!

Let's do one last thing! Create an awesome box shadow effect on the bottom of the slider to make it really pop using pseudo elements. We need to create a new element on both sides of the slider so we will use the ::before and ::after pseduo elements. We use the :: instead of : to help distinguish pseudo elements from pseduo classes. 

.mySlide::before, .mySlide::after {
  content: "";  / Create new empty element
  position:absolute; /*position is absolute so we can determine the exact placement*/
  height:40px;   
  width:45%;
  background:#000000;
  bottom:12px; /* Put the elements on the bottom and raise it up 12px from the bottom */
  z-index:-1; /* Send it behind the slider */
  
}
.mySlide::before {
  left:5px;
  transform:rotate(-2deg);  /*Rotate the element counter clockwise 2 degrees */
  box-shadow:10px 10px 15px 10px #444;
}

.mySlide::after {
  right:5px;
  transform:rotate(2deg); /*Rotate the element clockwise 2 degrees */
  box-shadow:-10px 10px 15px 10px #444;
}

That's it! You can adjust the color of the shadow as you wish as well as the blur and offset of the shadow.

 

I hope this tutorial has helped and if you have any questions or comments or suggestions, leave a comment below! 

View Demo!

 

 

 

Comments (2)

Rated 0 out of 5 based on 0 voters
This comment was minimized by the moderator on the site

This is the first visit to this site, you have to read the content posted along the way. After that I learned a lot from this help in the future. Cost or Price to make a website like apkpure

Tayyab Vega
This comment was minimized by the moderator on the site

Hi Tayyab. Thanks for the feedback! Sorry for the extremely late response. I haven't had any time to put into this lately, but I'm really glad to hear that you learned a lot from this! If you still want to talk at all about making a website, we...

Hi Tayyab. Thanks for the feedback! Sorry for the extremely late response. I haven't had any time to put into this lately, but I'm really glad to hear that you learned a lot from this! If you still want to talk at all about making a website, we can certainly do that.

Read More
Richard H.
There are no comments posted here yet

Leave your comments

  1. Posting comment as a guest. Sign up or login to your account.
Rate this post:
Attachments (0 / 3)
Share Your Location
© 2019 The Code Crypt. All Rights Reserved.