Jump to content

Automatic rollover with different intervals


flowe

Recommended Posts

Hi everybody

 

I have a rollover with 2 images, changing endlessly at equal intervals.

This is easily done using setInterval and makes no trouble.

 

Now I want the 2 images to change at unequal intervals.

I thought this would be easy too and wrote the attached code.

But I can't bring it to work, whatever I try.

 

Would anybody please help me?

Many thanks and kind regards - Henry

<html><head><title>…</title></head><script style = "text/javascript" >var rollover = new Array();rollover[0] = new Image(); rollover[0].src ="image_n_308x70.jpg";rollover[1] = new Image(); rollover[1].src ="image_d_308x70.jpg";var i = 0;var number = 0;var hold = 5000;while ( i == 0) {setTimeout( "change()", hold );function change() {document.rollover.src = rollover[number].src;if (nummer == 0) {number = 1; hold = 1000;} else {number = 0; hold = 5000;}}</script><body><img name="rollover" src="image_n_308x70.jpg" alt="" width="308" height="70"></body></html>
Link to comment
Share on other sites

A while loop constantly keeps running the same code over as fast as it can. By the time a second has passed you'll have a million timers going on which will run the same function one second after they were created. You're also trying to declare a function inside a loop, meaning it's redeclaring the function millions of times a second.

 

It's a bad idea to pass a string to setTimeout() or setInterval(). You should pass a function reference instead, like this:

setTimeout(change, hold);

The document.elementName method to refer to elements is not standard. The name attribute is not allowed on any element except <input>, <select> and <textarea>. Make sure you validate your code at http://validator.w3.org/

 

To access an element use the ID attribute and getElementById();

<img id="rollover" src="image_n_308x70.jpg" alt="Image" width="308" height="70">var image = document.getElementById("rollover");

Here's the solution to your problem:

// Creating an array the modern way// No need for new Image(), just remember the image namevar rollover = [    "image_n_308x70.jpg",    "image_d_308x70.jpg"];// Global variablesvar number = 0;var hold = 5000;// Set the timer, calling the function by referencesetTimeout(change, hold);// The functionfunction change() {    // Access the element by its ID    // Make sure the image has an id attribute    document.getElementById("rollover").src = rollover[number];    // Get next number and time interval    if(number == 0) {        number = 1;        hold = 1000;    } else {        number = 0;        hold = 5000;    }    // This function calls itself so that it will repeat    setTimeout(change, hold);}
Link to comment
Share on other sites

Hi Foxy Mod
Thanks again for your input. Your ready made solution solved my real life problem. As you see, as a non-professional I'm fairly out of date regarding JS. But I've learned several new tricks - as the best appears 'var rollover [ ..., ... ]'.
I don't understand 'calling the function by reference'. Could you please elaborate?
Why doesn't it work after adding the () to 'change()'? And why does it work again in Chrome/IE11/FF browsers after making it a string '"change()"'? I didn't find any in-depth explanation in 'JavaScript Function Invocation' in the JS Tutorial.
I 'invoked' http://validator.w3.org/ and 'earned' several errors, but none related to the issue just mentionned.
Another question: JS Tutorial proposes to use plain <script></script> statements, but validator demands <script type="text/javascript">. To me, it generally appears to be rather difficult to obtain conclusive advice...
Anyhow, thanks so far - Henry
Link to comment
Share on other sites

A function is "stored" somewhere. There are two things you can do with that function: Give a reference to where it is stored, or to call the function. To give a reference to the function, you write its name, to call it, you write its name and add the parentheses (). When you call the function it will run exactly the moment you call it. If what you want is to have the function called later, you need to just give a reference and not call it right on the spot.

 

Here's the difference between a reference and calling the function:

function five() {    return 5;}// This is a reference to the functionvar a = five;// On this line we call the function and save the result in the variablevar b = five(); // B is now "5"// We can also call the function by its reference:var c = a(); // C is now "5

setTimeout() and setInterval() can take one of two things as their first parameter:

1. A string of code2. A reference to a function

function showResult() {    var n = 5 + 3;    alert(n);}// Executing a string of code:setTimeout("var n = 5 + 3; alert(n)", 5000);// Running a function:setTimeout(showResult, 5000);

Executing a string of code is a bad idea because the browser has to run Javascript's parsing engine over again to turn that string into real code which makes the browser do a lot more work.

 

Another question: JS Tutorial proposes to use plain <script></script> statements, but validator demands <script type="text/javascript">. To me, it generally appears to be rather difficult to obtain conclusive advice.

 

The Javascript tutorial assumes you're writing in HTML 5, but your current document is not HTML 5, it's being interpreted as an old version of HTML which required the type attribute. You need to choose a version of HTML by putting the right <!DOCTYPE> declaration at the beginning of your code. It's important than your page is valid HTML so that Javascript and CSS will work as they should. You should read the HTML tutorial: http://www.w3schools.com/html/html_basic.asp

Link to comment
Share on other sites

Hi Foxy Mod

 

Thanks again - and back again. The two banners script works flawlessly as you suggested, but I failed miserably on expanding it to three banners, with banner nis appearing as every second and the other two alternating in first position. Incredible to implant an undetectable killer in just few lines...

 

This works:

<script style = "text/javascript" >var rollover = [                 // creating array by [...]    "_band-emo-308x70.jpg",       // rollover[item0]    "_band-nis-308x70.jpg"        // rollover[item1]];var number = 1;var hold = 7000;setTimeout(change, hold);function change() {    document.getElementById("rollover").src = rollover[number];    if (number == 1) { number = 0; hold = 35000; }    else { number = 1; hold = 7000; }    setTimeout(change, hold);}</script>

And this doesn't:

<script type="text/javascript">var rollover = [    "_band-emo-308x70.jpg",    "_band-nis-308x70.jpg",    "_band-rab-308x70.jpg"];var number = 1;var hold = 7000;var flag = emo;setTimeout(change, hold);function change() {    document.getElementById("rollover").src = rollover[number];      if (number == 1) {                               	hold = 35000;                     if (flag == emo ) { number = 2; flag = rab; }        if (flag == rab ) { number = 0; flag = emo; } } 	else { hold = 7000; number = 1; }    setTimeout(change, hold);}</script> 

Please correct... many thanks

flowe

Link to comment
Share on other sites

What you need now, instead of a toggle algorithm is a cyclical algorithm.

 

Let's have an array to determine which intervals go with which image:

var intervals = [    5000,    7000,    3000];

Now update the function to behave cyclically

function change() {    // Update image    document.getElementById("rollover").src = rollover[number];    // Set the new waiting time    hold = intervals[number];    // Update the iterator    number++;    // Make sure it cycles by going back to zero if it's too big    if(number >= intervals.length) {        number = 0;    }    // Next iteration    setTimeout(change, hold);}
Link to comment
Share on other sites

Hi Foxy Mod

 

with your kind and patient "shoe horn" activity, my - and my customers - idea is successfully implemented. Using your last proposal and what I've learned in this thread, I now have 4 banners with individual holding times and switching like clockwork. Many thanks!

 

This is the whole and final working code - never mind any possibly retro elements...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title></title></head><script style = "text/javascript" >var rollover = [    "_band-emo-308x70.jpg",    "_band-nis-308x70.jpg",    "_band-rab-308x70.jpg",    "_band-nis-308x70.jpg"];var intervals = [	7000,	7000,	4000,	35000];var number = 0;var hold = 7000;var lg = intervals.length;setTimeout(change, hold); // holding preloaded emofunction change() {	number++; 	if (number == lg ) { number = 0	};    document.getElementById("rollover").src = rollover[number];	hold = intervals[number];    setTimeout(change, hold);}</script><div style="position:absolute; top:0px; left:0px;"><img id="rollover" src="_band-emo-308x70.jpg" alt="image" width="308" height="70"></div></html>
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...