flowe Posted January 17, 2015 Share Posted January 17, 2015 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 More sharing options...
Ingolme Posted January 18, 2015 Share Posted January 18, 2015 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 More sharing options...
flowe Posted January 18, 2015 Author Share Posted January 18, 2015 Hi Foxy Mod Great many thanks for the friendly and profound answer. I'm sure it works without me fully understanding it yet, but I'll try and learn... Henry. Link to comment Share on other sites More sharing options...
flowe Posted January 21, 2015 Author Share Posted January 21, 2015 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 More sharing options...
Ingolme Posted January 21, 2015 Share Posted January 21, 2015 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 More sharing options...
flowe Posted January 28, 2015 Author Share Posted January 28, 2015 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 More sharing options...
Ingolme Posted January 28, 2015 Share Posted January 28, 2015 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 More sharing options...
flowe Posted January 29, 2015 Author Share Posted January 29, 2015 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now