JQuery

JQuery rotating banner slider with fade in/fade out effect

Note: This plugin still is not complete but it is ready for initial release but if you wish to get custom behaviour you will need to modify it yourself for the second. You will need at least JQuery v1.4 to use this plugin.

I have been making a little plugin for JQuery recently that allows for some one to make a fade in/out JQuery banner slider from a JSON source file. It can be viewed here: Test Page for j-slider (Yes I named it j-slider; I know, I’m a pikey).

This plugin is real simple all you need to make is a JSON data source like so:

[{"image":"slide_01.jpg"},{"image":"slide_02.jpg"},{"image":"slide_03.jpg"}]

This JSON file will be the source for all your slides. A you can see I have just specified 3 slides and 3 images, one image for each slide. After you have your source data you just need the CSS:

@CHARSET "ISO-8859-1";

.j-slider_outer{
}

.j-slider_inner{
	display:block;
	position:relative;
}

.j-slider_row{
	position:absolute;
}

.j_slider-slide_outer{
	position:absolute;
}

.j_slider-slide_active{
	display:block;
	z-index:45!important;
}

.j_slider-slide{
	display:block;
}

.j_slider-next, .j_slider-previous{
	overflow:hidden;
	font-size:15px;
	font-weight:bold;
	color:#ffffff;
}

.j_slider-next{
	display:block;
	position:absolute;
	right:0;
	z-index:45;
}

.j_slider-previous{
	display:block;
	position:absolute;
	left:0;
	z-index:45;
}

.j_slider-controls_outer{
	display:block;
	position:absolute;
	right:3px;
	bottom:5px;
	z-index:45;
}

.j_slider-controls_inner{
	float:left;
	height:16px;
	width:16px;
	font-size:12px;
	color:#ffffff;
	margin:0 3px;
	cursor:pointer;
	background:url("/images/j_slider/ibutton.png");
}

.j_slider-controls_active{
	background:url("/images/j_slider/button.png");
}

And the your actual page:

<html>
	<head>
		<title>Slider Test</title>
		<link rel='stylesheet' media='all' type='text/css' href='/css/j-slider.css' />
		<script type="text/javascript" src="/js/jquery.js" ></script>
		<script type="text/javascript" src="/js/j-slider.js" ></script>
	</head>

	<body>

	<script type="text/javascript">$(document).ready(function(){ $(".j-slider_outer").j_slider(); });</script>
	<div class="j-slider_outer"><div class="j-slider_inner"></div></div>


	</body>
</html>

And Ka POW! It is done! The plugin itself it really easy to understand but I have pasted a fully annotated version below:

(function($){
	var options = {
			"width":580,
			"height":164,
			"slide_speed":10000,
			"fade_speed":"slow",
			"json":"/modules/slider/data_source.json",
			"images":"/images/j_slider/",
			"side_nav":false,
			"bottom_nav":true,
			"cycle":true
	},
	methods = {
		init: function(opts){

			// Merge options so we have the users options
			options =  $.extend(options, opts);

			return this.each(function(){

				// Specify the variable required to make the slider
				var $this = $(this),
					thumbs = [],
					data = $this.data('j_slider');

				if(!data){
					// Get our source data
					$.getJSON(options.json, function(data){

						// Constrain the outer boxes
						$this.css({ "height": options.height+"px", "width": options.width+"px" });
						$this.children(".j-slider_inner").css({ "height": options.height+"px", "width": options.width+"px" });

						// Add our slider row (all our slides will go into here)
						$("<div class='j-slider_row'></div>").appendTo($this.children(".j-slider_inner").get());

						// Add the controls outer (all our slide controls go here)
						$this.children(".j-slider_inner").append("<div class='j_slider-controls_outer'></div>");

						// For each of the slides within the JSON file
						$.each(data, function(i, slide){

							// Form an ID
							id = "slide_"+(i+1);

							// Append the slkide itself
							$("<div class='j_slider-slide_outer j_slider-slide' id='slide_"+(i+1)+"'><img src='"+options.images+slide.image+"' alt=''/></div>").appendTo($this.find(".j-slider_row").get());

							// Add the slide to the buttons at the bottom (the white circle things)
							if(options.bottom_nav){
								if(slide.thumbnail && slide.thumbnail != undefined && slide.thumbnail != null){
									// Still needs to be done
								}else{
									$this.children(".j-slider_inner").find(".j_slider-controls_outer").append("<div class='j_slider-controls_inner j_slider-controls_active' id='"+i+"'></div>");
								}
							}
						});

						// Assign the controls an action.
						$this.children(".j-slider_inner").children(".j_slider-controls_outer").find(".j_slider-controls_inner").bind({ click: _goto });

						// Make first slide active
						$this.find(".j-slider_row").children("#slide_1").addClass("j_slider-slide_active");

						// Make all other slides hide
						$this.find(".j-slider_row").find("div:not(#slide_1)").css("display", "none");

						// Assign the inactive class to all control buttons that are not assigned to the first slide
						$this.find(".j_slider-controls_outer").children(".j_slider-controls_inner:not(#0)").removeClass("j_slider-controls_active");

						if(options.cycle){
							// If the user wants to cycle the slides then start the automated slider
							slider_timeout = setTimeout(next, options.slide_speed);
						}

						if(options.side_nav){
							// If user wants the slide menu navs then put them in
							$this.children(".j-slider_inner").append("<div class='j_slider-previous'><span><</span></div><div class='j_slider-next'><span>></span></div>");
							$this.children(".j-slider_inner").find(".j_slider-next").bind({ click: next });;
							$this.children(".j-slider_inner").find(".j_slider-previous").bind({ click: previous });
						}
					});
				}
			});
		},
		destroy: function(){
			return this.each(function(){

				// This function is kinda redundant and aint really needed
				var $this = $(this),
				data = $this.data('j_slider');

				// Namespacing FTW
				//$(window).unbind('.j_slider');
				data.j_slider.remove();
				$this.removeData('j_slider');

			});
		}
	},
	_goto = function(){
		// This function takes us to a specific slide
		// Stop the timeout to stop stupid clitches within animation.
		clearTimeout(slider_timeout);

		// Get the slide we are looking for
		var id = $(this).attr("id"), el = $(".j_slider-slide_outer:eq("+$(this).attr("id")+")").get();

		// Make it display (beneath the current one)
		$(el).css("display", "block");

		// Fade out the current slide
		$('.j_slider-slide_active').fadeOut(options.fade_speed, function() {

			// Take away the class from the one just faded out
			$(".j-slider_row").find(".j_slider-slide_active").removeClass("j_slider-slide_active");

			// Take the class away from the control button assigned to this slide
			$(".j_slider-controls_outer").find(".j_slider-controls_active").removeClass("j_slider-controls_active");

			// Add class assigned to goto slide to controls and show the slide
			$(".j_slider-controls_outer").find("div#"+id).addClass("j_slider-controls_active");
			$(el).addClass("j_slider-slide_active").show();
		});

		if(options.cycle){
			// Continue cycling if user wishes it
			slider_timeout = setTimeout(next, options.slide_speed);
		}
	},
	previous = function(){
		// This function goes to the previous slide
		// Lets clear timeout again
		clearTimeout(slider_timeout);

		// Get previous slide
		var index = 0, el = $(".j-slider_row").find(".j_slider-slide_active").prev();

		// If we are at the end show the last slide otherwise show the next one
		if(el.length > 0){
			index = $(".j_slider-slide_outer").index(el);
			el.css("display", "block");
		}else{
			index = $(".j_slider-slide_outer").index($(".j_slider-slide_outer").last());
			$(".j_slider-slide_outer").last().css("display", "block");
		}

		// Fade out the current slide
		$('.j_slider-slide_active').fadeOut(options.fade_speed, function() {

			// remove active class from current slide and remove the active class from the control button
			$(".j-slider_row").find(".j_slider-slide_active").removeClass("j_slider-slide_active");
			$(".j_slider-controls_outer").find(".j_slider-controls_active").removeClass("j_slider-controls_active");

			// If we are at the end we want to show the last one else show the next one
			if(el.length > 0){
				el.addClass("j_slider-slide_active").show();
			}else{
				$(".j_slider-slide_outer").last().addClass("j_slider-slide_active").show();
			}

			// Add active class to the control assigned with the index
			$(".j_slider-controls_outer").find("div#"+index).addClass("j_slider-controls_active");
		});

		if(options.cycle){
			//continue cycling if user wishes to
			slider_timeout = setTimeout(next, options.slide_speed);
		}
	},
	next = function(){
		// Same as the previous function only next instead of previous and first instead of last
		clearTimeout(slider_timeout);

		var index = 0, el = $(".j-slider_row").find(".j_slider-slide_active").next();

		if(el.length > 0){
			index = $(".j_slider-slide_outer").index(el);
			el.css("display", "block");
		}else{
			index = $(".j_slider-slide_outer").index($(".j_slider-slide_outer").first());
			$(".j_slider-slide_outer").first().css("display", "block");
		}

		$('.j_slider-slide_active').fadeOut(options.fade_speed, function() {
			$(".j-slider_row").find(".j_slider-slide_active").removeClass("j_slider-slide_active");
			$(".j_slider-controls_outer").find(".j_slider-controls_active").removeClass("j_slider-controls_active");

			if(el.length > 0){
				el.addClass("j_slider-slide_active").show();
			}else{
				$(".j_slider-slide_outer").first().addClass("j_slider-slide_active").show();
			}

			$(".j_slider-controls_outer").find("div#"+index).addClass("j_slider-controls_active");
		});

		if(options.cycle){
			slider_timeout = setTimeout(next, options.slide_speed);
		}
	},
	slider_timeout = null;

	$.fn.j_slider = function(method) {

		// Method calling logic
		if ( methods[method] ) {
			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			return methods.init.apply( this, arguments );
		} else {
			$.error( 'Method ' +  method + ' does not exist on jQuery.j_slider' );
		}

	};
})(jQuery);
Advertisements

2 thoughts on “JQuery rotating banner slider with fade in/fade out effect

  1. Sam,

    Nice, but you could improve it greatly by adding keyboard navigation, and change a little bit the code to have the choice between multiple effects…

    Another problem I see in your code is that you’re querying specific HTML elements such as div’s instead of using only class names, so we have to do the markup your way which is bad.

    Other than that, it’s cool!

    1. Thanks 🙂

      I agree with your points. I gotta sort this plug-in out some time. I have it on my list :).

      I think I traversed more than picked classes when creating the elements for a reason…though it was a while ago so I’m just stuck here trying to remember :P.

      I think it was speed actually, the difference between creating via class selectors and JQuerys DOM array….but can’t totally remember.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s