26 January 2012

Free Javascript for Rotating Website Banner or Fading Slideshow - standalone

As flash becomes less widespread I've had more and more instances where I need to create website banners in Javascript rather than my old flash approach. Today I've decided to share my method with my adoring public (that's you!).

This method is completely standalone and does not require jQuery or any other plugin or library. It has been tested and works in latest versions of all browsers.

View a demo here (right click to get the whole source at once) or view the step-by-step instructions below...

Please see my note before copying my code - thank you! >

Add this between your head tags. You can tweak the speeds etc in the BANNER SETUP section at the top.

//ROTATING BANNER BY CIARAN O'KELLY 2012 - BLOG.CRONDESIGN.COM

//BANNER SETUP:
var imageCount = 5;  //how many images in total?
var changeSpeed = 3;  //how many seconds between fades?
var fadeSpeed = 0.5; //how many seconds should the fade take?
var fps = 25;  //animation frames per second

//BANNER FUNCTIONS:
var topImgID
var changeInterval

function $(id){ //just a shortcut function:
 return(document.getElementById(id));
}

function changeOpac(obj, opacity) {//change the opacity for different browsers:
 obj = obj.style; 
 obj.opacity = (opacity / 100);
 obj.MozOpacity = (opacity / 100);
 obj.KhtmlOpacity = (opacity / 100);
 obj.filter = "alpha(opacity=" + opacity + ")";
}

function changeImage(){
 var nextImgID = ( topImgID+1 <= imageCount ? topImgID+1 : 1 ); //get id number of next image in list
 var nextImg = $('banner'+nextImgID);
 var lastImg = $('banner'+topImgID);
 var opac = 0;
 changeOpac( nextImg, opac) //make next image invisible, then bring it to the top:
 lastImg.style.zIndex = 2;
 nextImg.style.zIndex = 3;

 var fadeInterval = setInterval(function(){ //run fade on interval:
  if(opac < 100){//continue fade:
   opac += Math.ceil(100/(fadeSpeed*fps));
   changeOpac(nextImg, opac);
  }else{//end fade:
   lastImg.style.zIndex = 1;
   clearInterval(fadeInterval);
  }
 }, 1000/fps)

 topImgID = nextImgID; //prepare next fade
}

function startBanner(firstImageID){
 topImgID = (firstImageID==undefined ? 1+Math.floor(Math.random()*(imageCount)) : firstImageID);
 $('banner'+topImgID).style.zIndex = 2;
 changeInterval = setInterval(changeImage, changeSpeed*1000);
}
Add this to your stylesheet and tweak to your liking:

.banner{position:absolute; z-index:1; height:230px; width:720px; top:0px; background:#FFF; border:solid 1px #CCC}
.banner h1{position: absolute; bottom:20px; right:20px; font-style:italic; color:#444; float:right; width:50%; font-size:40px; text-align:right; line-height:100%;}
#banner1{background-image:url(banner1.jpg);}
#banner2{background-image:url(banner2.jpg);}
#banner3{background:#F90}
#banner4{background:#FFC}
#banner5{background:#99CCFF}
Add this to your html and tweak to your liking:

<div id="banner2" class="banner">
    <h1>It runs on a loop</h1>
</div>
<div id="banner3" class="banner">
    <h1>The images are actually div tags</h1>
</div>
<div id="banner4" class="banner">
    <h1>So they can contain text, colours or other content</h1>
</div>
<div id="banner5" class="banner">
    <h1>You can control the speed, the start image & number of images</h1>
</div>
<div id="banner1" class="banner">
    <h1>This banner fades between images</h1>
</div>
Finally, if you want the banner to automatically start, add this to your body tag. 1 is the id of the first image you want to show. Leave it blank to choose a random image.

<body onload="startBanner(1)">

65 comments:

Anonymous said...

How would I make each banner frame link to a url?

Ciarán O'Kelly said...

You can add links to each frame inside the div tags. If you want the whole banner to be clickable, simply style the link with display:block; width:100%; height:100%;

Anonymous said...

Awesome, thanks. Will give it a try.

Anonymous said...

Works great. I was trying everything except the obvious to get links to function.

Anonymous said...

how can i stop the loop? only single loop only?

Ciarán O'Kelly said...

Something like this should stop the loop at the end:
if(nextImgID == 1) clearInterval(changeInterval);

Add this line below the comment that says //end fade:

shona16 said...

Thanks so much for this!!! It runs so well and is so easy to tweak - really appreciate that as I'm still a beginner. Thanks for this great support.

Iztok said...

Thank you

Anonymous said...

Thank you for your code.
This is just what I was searching for.

Anonymous said...

Thanks so very much for this. It works wonderfully. It's not currently working in safari but it was at first I've got to go back and make sure I didn't change anything.

Anonymous said...

Dear Ciarán,

thanks for this great script. Just finished adding it to my site. Have a question though. Do you have a solution how to pause the banner when hoovered?

Zachary Freed said...

this works great...just one problem. how in the world do you center this? ive tried every which way and it won't budge.

Ciarán O'Kelly said...

Hi,
To pause the banner you can simply use
clearInterval(changeInterval)
To start it again you need to reset the interval:
changeInterval = setInterval(changeImage, changeSpeed*1000);

@Zachary I dont know what you mean by "this"? The banner is absolutely positioned so you would need to manually set the left & top attributes in the .banner{} style if you wanted to center the whole banner. Try this:
.banner{left:50%;}

Anonymous said...

can we add two banners in one page. its not working

Anonymous said...

thank you!

Dan said...

I tried to center it also, using the left:50% like you suggested to Zachary before. That just moved the left edge of the div to 50%. Is there a way to "relatively" position the banner so that I can center it horizontally ? My website is centered horizontally so I would need the slideshow to be centered also. Thanks in advance!! Do you take contributions ?

Ciarán O'Kelly said...

Sorry @Dan I should have said, you need to add a negative left margin to the absolute positioning to make the banner display in the center of its parent:
.banner{ left:50%; margin-left:-360px; }
(donations link added now ;-) )

@Anonymous, yes, it is technically possible to get two banners working on each page. You would need to go through the script and make the global variables (the ones that are set a the top of the script) unique to each banner. It will probably take a bit of fiddling to get it working.

Dan said...

How much would you charge to customize this script so that it would no longer have an absolute reference, so that I could relatively place it where ever I needed it ?

Ciarán O'Kelly said...

Hi Dan, there is no way to do this without absolute positioning unfortunately. The whole point is that the divs are stacked on top of each other and faded out as needed. If you put position:relative on the parent element of the main banner div, you may be able to position it in a more familiar way

Web Design said...

Nice Blog...!!

Ronald said...

Hi,

The first part seems to disagree with other script, is there a way to name the function:

function $(id){
return(document.getElementById(id));
}

And later in your script:

var fadeInterval = setInterval(function(){ //run fade on interval:

Thanks

Anonymous said...

Thanks Dear

Anonymous said...

It works perfectly, thanks a lot!
PS. Your notice is in my code ;)

Anonymous said...

Hi thanks for this.
I have it working in Chrome & Firefox but for some reason it doesnt scroll in ie8 it just sits on the first slide, any ideas?
Thanks in advance

Orthodox Daily said...

Hey man, thanks a lot for this. Really helped out.

Anonymous said...

This is wonderful. Suggestion for those wanting to format this differently (i.e. centred, more on a page, etc.). I created the slideshow in its own page just as you have it. Then, in the page where I wanted the formatting, I put an iframe with height and width the same as the slideshow and with no border. The src of the iframe is the slideshow.htm. Worked like a charm.

Kelvin Tan said...

Hi

would you know how to include the numbering to the rotating banner? so user can click to view which banner they want

eg. this website
http://www.rubytuesday.com/

Luviana said...

I'd also like to add numbering or a thumbnail to select which is displayed like Kelvin asked.

Steve said...

I think this could my problem but I need some help.

1. When I paste the first code inside the Head tag it is not seen as code, only black text. I tried saving that code as a separate .js file and then referencing it from inside my Head tag but I don't think it's being found.


2. Is the CSS needed? When I used it everything stacked up at the top of my sidebar. When I removed it everything lined up in my sidebar as I wanted.

3. I'm using some other code to only display as many banner ads as the length of the Content Div so I don't get over-run. It works well but right now the rotation code is not working so I can't be sure of anything.

var sb=document.getElementById('sidebar');
while (sb.offsetHeight>document.getElementById('content').offsetHeight){
sb.removeChild(sb.lastChild);
}


4. Finally, my goal is to not hard code my banner ads into each page since that makes updates a real pain. How do I use your code to access another file containing all of my available banner ad code so I can just update my ads from a single file.

You can see what I have so far on my test page. I appreciate the help.

http://www.christian-life-advisor.com/5-things-to-consider2.html

Merry Christmas!
Steve

Steve said...

OK, I apologize for part of my above post.

#1 is fine once I place the code within the correct tags...duh!

#2 is still a bit odd. I eliminated the top two .banner lines and now my banners display in the correct location instead of stacked up, but I'm still not seeing the point of the CSS.

I think the real issue I'm having is how to go about putting all of my CJ, ShareSale, and LinkShare banner code into a separate file that can be read and pulled into each page on my site instead of hard-coding the banner code into each page. It seems that any solution I have found has me hard-coding the banner code into my pages and that is not a desirable solution. Any help is greatly appreciated.

Peter said...

Hey Steve,

I've been trying to get a banner slideshow to work as well and I was wondering how you got #1 to work.
I've currently saved the first code in a separate file as a javascript and reference it within my html code.

Peter said...

nevermind, just got it to work

NaN said...

Hi, I've used your code and everything works wonderfully except when I try to implement it with my webstore. I'm using a template from volusion and the code seems to push the banner to the very top of the screen. Is there a way to stop it from doing that so that it can follow the format of my template?

Anonymous said...

When I saved a copy of the script to experiment, i found that it would first display banner3, then banner2 for a split second then banner3 again, then run fine after that. (Firefox 17.0.1)

Changing banner3 to have a z-index of 1 seems to resolve the problem, but I have more testing to do.

Very nice script by the way :-)

Anonymous said...

GREAT SCRIPT!!! However, I have a strange error that I hope you can help me with.

On my banner, I only have 2 images that rotate.

On FIRST rotation and ONLY on the first rotation, the second image will appear twice!

I just want to rotate between image 1, image 2, image 1, image 2 in an endless loop.

What happens is this.. image 1, image 2, image 2, image 1 and then it corrects itself.

Any suggestions?

Thank you

Anonymous said...

i fixed it, nevermind. Great script. thx

Anonymous said...

By default this awesome script is always justified to the top left.

How can I pin it to one exact location so it wont move under any circumstance?

Thank you

Anonymous said...

Nevermind, .banner{ left:50%; margin-left:-360px; } works 100% to center it! Will donate when I finish project. THANK YOU!

Anonymous said...

Why does the script start banner #5 first even if you told it to start with banner #1 first using the "body onload" code you provided???

I noticed that even your demo does this as well!!!????!!!

All my script settings are at 100% default!!!

I hope this can be fixed so I can use this awesome script.

Thank you

Anonymous said...

A previous question concerning linking to a website...

"You can add links to each frame inside the div tags. If you want the whole banner to be clickable, simply style the link with display:block; width:100%; height:100%;"

What is the exact coding to add the url links of jpeg banner ads?

William Praniski said...

hi, the banner is working fine for me, the only problem is that it appears on top of my header, which is an image inside a div.
below my div tag with the image i still have a nav bar and then the body.
how can i make the banner appear below my nav bar??? it keeps appearing on top of everything. thanks.

Anonymous said...

Ciaran,

This banner rotation works great in Chrome, Safari and Firefox but for some reason in I.E. 8 the banners are not rotating and it starts and is stuck on the third banner in a group of 5 banners.

Can you give some hints in how to resolve please?

Anonymous said...

how can you center the banner VERTICALLY?

Anonymous said...

None of this works for me.?

I put all the code within the text in as designated, but all the stuff in the head tag simply appears as text on the page and the banner does not rotate anything. It just appears as a static block on the lower right side of my page. Any suggestions?

Thank you!

Janice Penni said...

Hi there, I have tried this great tutorial with 2 changes within the html and css, but when I run the webpage in a browser, the rotation does not work, it just shows an image of one of the banners. Please can you advise I would really appreciate it.

Thanks

Larry Muller said...

Ciaran,

Great Script it works well in all five major browsers except the last photo in the slide show appears first then jumps to the beginning of the slide show and it works beautifully after that.

By chance do you have any recommendations that will correct that? I have it on several pages on my site but I have changed the number of photos and and increased the duration between each fade.

Thanks for the great script and any help you can lend.

BASU said...

my last banner is place permanently visible in fron rest banner a quickly fade and hide behind it whats matter is that could you help me out with this

Sushant said...

thank you for the great tips.
The problem is, While applying it to my blog the blogspot is not allowing to save template - it is not allowing me to save the template and following code error
1. in "var nextImgID = ( topImgID+1 <= imageCount ? topImgID+1 : 1 ); //get id number of next image in list" --- it is not accepting "<" sign
2. in " if(opac < 100)" --- here also it is not accepting "<" sign.
if I replace them with "=" then it saves but effect doesn't work.
Kindly help with step by step guidance for blogger.
Thank you in advance.

Sushant said...

put style in css template...
tried to correct the code with
"script type="text/javascript"
//![CDATA[
...code...
//]]
/script
method.
blogger let me save the template but no effect.
also advise how to use a picasa or google drive image link
please see the following link and advise
http://testbloglan.blogspot.in/

Sushant said...

Dear Corn,

Eagerly waiting for your solution.

Regards
Sushant
http://testbloglan.blogspot.in/

Jeff said...

Can someone please make this more clear?

"You can add links to each frame inside the div tags."
please show me an example.

"simply style the link with display:block; width:100%; height:100%;"

please show me an example with your code you provided.

jeff said...

Ok think i solved the block link issue, this site won't let you post code so I made and image link

See code here

Anonymous said...

How can I change the background-image into a local pic? #banner1{
background-image:url('C:\Users\Shyamie's\Desktop\html\Prelim website\Banner\b.jpg');
}

it doesnt work :(

kamilovouno said...

Hi,
I tried to use the above code in Microsoft Web Matrix but all I get is error message after error message. i am a beginner in terms of this type of coding.
Can you give me some advice as to what I need to do?

Anonymous said...

Very nice piece of code. THank you for posting.

Anonymous said...

Would like to donate as you helped me out but it doesn't bring up an email to send some money for some coffee to...
send me an email

info@blueaspectdesign.com.au

Cheers
Ben

Jose David Lopez Medina said...

Hello,

Thank you very much for this code. I applied with some changes and the banner itself is working well… but:

I need to put the div for the banner under my nav for the menus, which are drop down menus written on html and css. This kind of menu needs the position:absolut; for the ul that make the actual drop down.

The nav need to be relative to let the uls be absolute. Now, with the banner below my drop down menus are hidden by the banner when displayed, they are "behind" the banner, and is obvious that the menus must be on top of everything...

How can I fix that problem?

I will thank you if you post your answer copied to yuvarsi@gmail.com

When I got this working and I won't need any other type of rotating banner, I will donate...

Ian Howarth said...

Hi,

This nice snippet works well, thanks. The only problem i have is that with a moderately large image "stack", there's a significant pause before the first image shows up (followed by a very fast transition to the second image). I guess this is because the whole stack is loaded before the rotation starts. Any simple way of preloading the first image? (I've tried crude work-rounds, like specifying the elsewhere, without success.)

Ciarán O'Kelly said...

For those concerned about the last image appearing before the others and flashing through the other banners, I believe putting the first image last in the html should sort this out for you. I've updated the example code to demonstrate.

@ben: I've repaired the donate button - thanks for your donation - very kind of you.

@Jose: You can use CSS z-index to position your position:absolute dropdown menus above the banner.

@Ian: Not sure but you could try a very simple preload inside your body tag at the top:
<script type="text/javascript"> var img=new Image(); img.src="myFirstBanner.jpg"; </script>
Alternatively, try some of these techniques: http://stackoverflow.com/questions/4211519/controlling-image-load-order-in-html

@Others: Sorry, I can't help with installing this banner on third party sites or CMS templates

Anonymous said...

Any idea if it's possible to use play/pause/forward/back controls with this?

On my old slides I used some png images floated over the slides as controls and can't remember how I'd set that up

Ciarán O'Kelly said...

Yes should be simple enough. Only gets complicated if you wanted to automatically run the slideshow until the buttons are pressed. Something like this should work: (this is untested)

Play: startBanner(1)
Pause: clearInterval(changeInterval)
Next: changeImage()
Previous: This one is tricky and would require adding a parameter to changeImage() to instruct it to go backwards rather than forwards

Madhan said...

Its Looking So creative visit: http://www.dreamdestinations.in/

Anonymous said...

Amazing, thanks so much

Kristina said...

Hi, Was reading your blog and I am very satisfied with your job. I am very creative person and want to add some features to my website. Can you pls contact me:support@ulovime.com?
Thanks and have a nice day!

Anonymous said...

Hi, is it possible to show 3 images horizontal with changing/fading ?

Thanks,
Bernard

Post a Comment

Cron Design Studio: Dublin based web design & software development