jQuery Image Slideshow Plugin
A nice photo goes a long way towards making a design stand out. But we at Tutorialzine realized that sometimes a single picture is not enough and what you really need is a smooth slideshow of images to capture the user's attention and bring dynamics to the app. However, the implementation of such slideshows can sometimes be tricky, so we decided to make a tiny plugin to do the job for you.
How it works
It's really simple! First, you have to insert an image into the html as you would normally do. After that's done, you have to add a data attribute - data-slideshow
- and set its value to be the path of a series of images that you'd like to be turned into a slideshow:
<img src="...." data-slideshow="img1.jpg|img2.jpg|img3.jpg" />
All that is left, is to include our plugin in your page, call its slideShow() method and your slideshow is good to go!
The Code
The plugin consists of a JavaScript file and a CSS one.
We'll start with the .js file!
assets/jQuery-slideshow-plugin/plugin.js
This file holds a regular jQuery plugin. First of all we need to define our default options.
options = $.extend({ timeOut: 3000, // how long each slide stays on screen showNavigation: true, // show previous/next arrows pauseOnHover: true, // pause when hovering with the mouse swipeNavigation: true // (basic) support for swipe gestures }, options);
The basic idea is that we take the sources from the data-slideshow
attribute of a certain image and insert them into a div as its background. This div has the dimensions of the original picture and after it has collected all the images for the slides (including the one we started with) replaces it. Let's look at the code to make it a bit clearer.
// Variables var intervals = [], slideshowImgs = [], originalSrc, img, cont, width, height, // Creates an object with all the elements with a 'data-slideshow' attribute container = this.filter(function () { return $(this).data('slideshow'); }); // Cycle through all the elements from the container object // Later on we'll use the "i" variable to distinguish the separate slideshows from one another for (var i = 0; i < container.length; i++) { cont = $(container[i]); width = container.eq(i).outerWidth(true); height = container.eq(i).outerHeight(true); // For every separate slideshow, create a helper <div>, each with its own ID. // In those we'll store the images for our slides. var helpdiv = $('<div id="slideshow-container-' + i + '" class="slideshow" >'); helpdiv.height(height); helpdiv.width(width); // If this option is enabled, call a function that appends buttons if (options.showNavigation) { createNavigation(); } // Append the original image to the helper <div> originalSrc = cont.attr('src'); img = $('<div class="slide" style="background-image: url(' + originalSrc + ')">'); img.appendTo(helpdiv); // Append the images from the data-slideshow attribute slideshowImgs[i] = cont.attr('data-slideshow').split("|"); for (var j = 0; j < slideshowImgs[i].length; j++) { img = $('<div class="slide" style="background-image: url(' + slideshowImgs[i][j] + ')">'); img.appendTo(helpdiv); } // Replace the original element with the helper <div> cont.replaceWith(helpdiv); // Activate the slideshow automaticSlide(i) }
Upon activation the images start to fade in and out after one another automatically.
Depending on the settings we can also control the slideshow by clicking and hovering.
Thanks to hammer.js we made it possible to swipe through the pictures, as well.
Let's check out the functions that move the slides around!
// Slideshow auto switch function automaticSlide(index) { // Hide all the images except the first one $('#slideshow-container-' + index + ' .slide:gt(0)').hide(); // Every few seconds fade out the first image, fade in the next one, // then take the first and append it to the container again, so it becomes last intervals[index] = setInterval(function () { $('#slideshow-container-' + index + ' .slide:first').fadeOut("slow") .next('.slide').fadeIn("slow") .end().appendTo('#slideshow-container-' + index + ''); }, options.timeOut); } // Pause on hover and resume on mouse leave if (options.pauseOnHover) { (function hoverPause() { $('.slideshow').on({ 'mouseenter.hover': function () { clearInterval(intervals[($(this).attr('id').split('-')[2])]) }, 'mouseleave.hover': function () { automaticSlide($(this).attr('id').split('-')[2]) } }); })() } // We use this to prevent the slideshow from resuming once we've stopped it function hoverStop(id) { $('#' + id + '').off('mouseenter.hover mouseleave.hover'); } // Create the navigation buttons function createNavigation() { // The buttons themselves var leftArrow = $('<div class="leftBtn slideBtn hide">'); var rightArrow = $('<div class="rightBtn slideBtn hide">'); // Arrows for the buttons var nextPointer = $('<span class="pointer next"></span>'); var prevPointer = $('<span class="pointer previous"></span>'); prevPointer.appendTo(leftArrow); nextPointer.appendTo(rightArrow); leftArrow.appendTo(helpdiv); rightArrow.appendTo(helpdiv); } // Slideshow manual switch if (options.showNavigation) { // This shows the navigation when the mouse enters the slideshow // and hides it again when it leaves it $('.slideshow').on({ 'mouseenter': function () { $(this).find('.leftBtn, .rightBtn').removeClass('hide') }, 'mouseleave': function () { $(this).find('.leftBtn, .rightBtn').addClass('hide') } }); // Upon click, stop the automatic slideshow and change the slide $('.leftBtn').on('click', function () { // Clear the corresponding interval to stop the slideshow // ( intervals is an array, so we give it the number of the slideshow container) clearInterval(intervals[($(this).parent().attr('id').split('-')[2])]); // Make the last slide visible and set it as first in the slideshow container $(this).parent().find('.slide:last').fadeIn("slow") .insertBefore($(this).parent().find('.slide:first').fadeOut("slow")); hoverStop($(this).parent().attr('id')); }); $('.rightBtn').on('click', function () { // Clear the corresponding interval to stop the slideshow clearInterval(intervals[($(this).parent().attr('id').split('-')[2])]); // Fade out the current image and append it to the parent, making it last // Fade in the next one $(this).parent().find('.slide:first').fadeOut("slow") .next('.slide').fadeIn("slow") .end().appendTo($(this).parent()); hoverStop($(this).parent().attr('id')); }); } // Change slide on swipe // Same as the 'on click' functions, but we use hammer.js this time if (options.swipeNavigation) { $('.slideshow').hammer().on({ "swiperight": function () { clearInterval(intervals[($(this).attr('id').split('-')[2])]); $(this).find('.slide:last').fadeIn("slow") .insertBefore($(this).find('.slide:first').fadeOut("slow")) }, "swipeleft": function () { clearInterval(intervals[($(this).attr('id').split('-')[2])]); $(this).find('.slide:first').fadeOut("slow") .next('.slide').fadeIn("slow") .end().appendTo($(this)); } }) }
Finally, let's take a quick look at some of the css.
assets/jQuery-slideshow-plugin/plugin.css
We want all the images for our slides to stack on one another, so we give them the "sliding" class. It also makes them fit the entire slideshow div.
.sliding { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-position: center; background-size: cover; }
Then we set a z-index of 10 to the buttons to place them on top of the pictures.
.slideBtn { position: absolute; z-index: 10; width: 50px; height: 100%; cursor: pointer; } .leftBtn { left: 0px; background: linear-gradient(to right, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0)); } .rightBtn { right: 0px; background: linear-gradient(to left, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0)); }
Lastly, we make triangle arrows out of css borders and put them on top of everything with a z-index of 9001;
.pointer { position: absolute; top: 50%; margin-top: -32px; z-index: 9001; left: 12px; opacity: 0.8; } .previous { width: 0; height: 0; border-top: 20px solid transparent; border-bottom: 20px solid transparent; border-right: 20px solid white; } .next { width: 0; height: 0; border-top: 20px solid transparent; border-bottom: 20px solid transparent; border-left: 20px solid white; right: 12px; left: auto; }
Using the plugin
To use the plugin, include assets/jQuery-slideshow-plugin/plugin.css to the head of your page, and assets/jQuery-slideshow-plugin/plugin.js after your copy of the jQuery and Hammer.js libraries.
To initialize the plugin use this piece of code and feel free to change the settings' values.
(function ($) { $('#activate').on('click', function () { $('img').slideShow({ timeOut: 2000, showNavigation: true, pauseOnHover: true, swipeNavigation: true }); }(jQuery));
Done!
With this we round up the tutorial. We hope that you'll give the plugin a go. We did our best to make it as easy and fun to use as possible, while still maintaining a reasonable functionality. For any recommendations, questions and opinions, feel free to leave a comment below.
Bootstrap Studio
The revolutionary web design tool for creating responsive websites and apps.
Learn more
Exactly what I was looking for my latest project. Much appreciated. Thanks.
Nice plugin, but you can use the fade effect in "hover"
Since you are using "bootstrap", just change:
i really do like this plugin. thank you for your effort!
Danny - Great tutorial. There is a small glitch when you resize your browser down. The images scale down, but then stay that size when you resize your browser up.
Nice, very simple (but in the meantime- professional and useful) plugin. Good luck in making more tutorials and plugins!
Hi,
nice, but how to set slideshow automatically without clicking activating button?
Hi, and thanks for the question!
To get the slideshow going simply call the slideShow() function on a jQuery selector for all img tags. To make it start automatically on page load you might have to add the code in $( document ).ready(), if you already haven't.
Example:
$( document ).ready(function() {
$('img').slideShow();
});
The activation button isn't a part of the plugin - it's just for the demo. We wanted to showcase the effects of the plugin so we call the slideShow() function when the button is clicked, thus activating the slide changes.
Hi Danny,
There are over 200 lines of code in the .js file
Where would I add the $(document).ready(fu.... command ?
Also, I love this slider, but with limited web development experience I'm having trouble setting this up. Trying to compare your "page source" code from the demo with what you've written here in the instructions, but everything doesn't jive dude.
For instance:
"To use the plugin, include assets/jQuery-slideshow-plugin/plugin.css to the head of your page, and assets/jQuery-slideshow-plugin/plugin.js after your copy of the jQuery and Hammer.js libraries."
The last line for the plugin.js file doesn't exist in your demo code. So where exactly do I put it ?
Sometimes when we are good at what we do (and you are !) we can miss a few things when laying out instructions like you have here.
Thank you very much for this .img slider ... I hope that I can get it running, because I like it better than most of the other stuff I've looked at.
Thanks,
Vic
Hi Victor and thanks for the question!
The $(document).ready() function can go anywhere in you custom JavaScript file. If you look at the demo, you will see there are four .js files included: jQuery, Hammer.js, the plugin from the article, and demo.js where we actually use the plugin itself - you should place $(doucment).ready there.
I hope I've cleared things up a bit.
Hi Danny,
Thanks for the nice plugin. I'm using it to display event photo at company's lobby.
I have a question to display landscape and portrait photos randomly, the portrait photo always missing people's head, may I know how can I make the css auto resize photo?
Dear Danny,
I really like your slider! Awesome. Could you please help me? I must have really messed it up? It's not working for me. Please see below
http://billcorbitt.com/TimYoung/index.html
Hi Bill,
You've setup everything correctly, the only thing you need to do is start the slideshow.
To do this go to the demo.js file, delete everything inside it, and instead add the following code:
This will start the slideshow automatically when the page is opened.