PDA

View Full Version : loop, stop, and then refresh?



dukevn
12-09-2009, 03:10 AM
Hi all,

My title says quite a bit of what I want to do: I want to create a page that can automatically refresh every, say 1 minutes. Each time when the page loads, it should auto load and loop some sites through an iframe. I came up with the below code:

<html>
<head>
<meta http-equiv="refresh" content="60">
<title>Refesh and Loop</title>
<script type="text/javascript">

var pages = [];
pages[0] = "http://www.google.com";
pages[1] = "http://www.bing.com";
pages[2] = "http://www.ask.com";
pages[3] = "http://www.altavista.com";

var i = 0;

function loopFrame() {
// get the frame
var frame = document.getElementById("iFrame");
frame.src = pages[i];
}

function updateFrame() {
if ( i<pages.length ) {
setTimeout(function(){loopFrame();}, 5000);
i++;
} else {
var frame = document.getElementById("iFrame");
frame.src = pages[0];
}
}
</script>
</head>
<body>
<iframe id="iFrame" src="http://www.google.com" onload="updateFrame();" width="100%"
height="100%" name="youriframe" frameborder="1" vspace="0" hspace="0"
marginwidth="0" marginheight="0" scrolling="yes" noresize>
</iframe>
</body>
</html>
This is actually not doing what I want. The code still loops forever and certainly eats up a lot of CPU. My question is: how to tell the updateFrame function to stop when the loop already finished the last page? Is there a command in javascript to do that?

EDIT: I think I did a bad job explaining above. I wonder what code I should use in the else {} condition that simple stop updateFrame function. Or any other suggestion for updateFrame that just runs setTimeout command when i is smaller than the length of pages.

Thanks,

D.

jscheuer1
12-09-2009, 06:39 AM
Well, none. If you load anyway, even when i is out of range, you keep triggering the onload event, and at that point in rapid succession. Also, why a meta refesh? You may loop the iframe back to the start without refreshing the page. Then, for that matter, why only 5 seconds between iframe changes? May as well use up the whole minute, or use less than a minute between ending and starting over. Why end at the beginning? When the page reloads and/or the loop starts over, there will be no perceptible change, though some browsers will appear to reload the iframe.

All that said, other than fix some code irregularities and the rapid succession changes that occur as i goes out of range, here's a working demo of what I think you say you want:


<html>
<head>
<meta http-equiv="refresh" content="60">
<title>Refesh and Loop</title>
<script type="text/javascript">
(function(){
var frame, i = 0, pages = [], attach = (function(){
return window.addEventListener? function(el, ev, f){el.addEventListener(ev, f, false);} :
window.attachEvent? function(el, ev, f){el.attachEvent('on' + ev, f)} : function(){return;};
})();
pages[0] = "http://www.google.com";
pages[1] = "http://www.bing.com";
pages[2] = "http://www.ask.com";
pages[3] = "http://www.altavista.com";

function updateFrame(){
if (i++ < pages.length){
setTimeout(function(){frame.src = pages[i % pages.length];}, 5000);
}
}

function load(){
frame = document.getElementById('iFrame');
attach(frame, 'load', updateFrame);
frame.src = pages[0];
};

attach(window, 'load', load);
})();
</script>
</head>
<body>
<iframe id="iFrame" src="about:blank" width="100%"
height="100%" name="youriframe" frameborder="1" vspace="0" hspace="0"
marginwidth="0" marginheight="0" scrolling="yes" noresize>
</iframe>
</body>
</html>

But if you consider some of my other questions and want help to implement any of the procedures they suggest, or just want more help in general, let me know.

dukevn
12-09-2009, 02:49 PM
Well, none. If you load anyway, even when i is out of range, you keep triggering the onload event, and at that point in rapid succession. Also, why a meta refesh? You may loop the iframe back to the start without refreshing the page. Then, for that matter, why only 5 seconds between iframe changes? May as well use up the whole minute, or use less than a minute between ending and starting over. Why end at the beginning? When the page reloads and/or the loop starts over, there will be no perceptible change, though some browsers will appear to reload the iframe.What I want is to have two loops in a page: it refreshes (or reloads, or anything similar) in a certain amount of time (1 min is just example); in each of its refresh, it should visit through some certain sites in a certain amount of time (4 sites and 5 seconds are just example). It should not end at the beginning, but I do not know which command I should put there, so I just put those commands for example only.

All that said, other than fix some code irregularities and the rapid succession changes that occur as i goes out of range, here's a working demo of what I think you say you want:


<html>
<head>
<meta http-equiv="refresh" content="60">
<title>Refesh and Loop</title>
<script type="text/javascript">
(function(){
var frame, i = 0, pages = [], attach = (function(){
return window.addEventListener? function(el, ev, f){el.addEventListener(ev, f, false);} :
window.attachEvent? function(el, ev, f){el.attachEvent('on' + ev, f)} : function(){return;};
})();
pages[0] = "http://www.google.com";
pages[1] = "http://www.bing.com";
pages[2] = "http://www.ask.com";
pages[3] = "http://www.altavista.com";

function updateFrame(){
if (i++ < pages.length){
setTimeout(function(){frame.src = pages[i % pages.length];}, 5000);
}
}

function load(){
frame = document.getElementById('iFrame');
attach(frame, 'load', updateFrame);
frame.src = pages[0];
};

attach(window, 'load', load);
})();
</script>
</head>
<body>
<iframe id="iFrame" src="about:blank" width="100%"
height="100%" name="youriframe" frameborder="1" vspace="0" hspace="0"
marginwidth="0" marginheight="0" scrolling="yes" noresize>
</iframe>
</body>
</html>

But if you consider some of my other questions and want help to implement any of the procedures they suggest, or just want more help in general, let me know.
Your code does the main thing of what I wanted. The only tiny thing is that it stops at the beginning.

Honestly I can understand some portion of your code, but some of them are mystery for me :). What does
(function(){...})()do, and the attach var
attach = (function(){
return window.addEventListener? function(el, ev, f){el.addEventListener(ev, f, false);} :
window.attachEvent? function(el, ev, f){el.attachEvent('on' + ev, f)} : function(){return;}; is quite advance, I can not get any sense out of it :(

Thanks,

D.

jscheuer1
12-09-2009, 04:20 PM
This:


(function(){...})()

usually with an appropriate terminus at the end (, or ;) depending upon where it appears in the code, unless as the last property/item in a literal object or array, is the self executing anonymous function. It is used twice in the code. First as a container/wrapper to limit the scope of the code. It makes the code entirely private, so as that its variable and function names cannot conflict with any other code you may add to the page. Second as a function to return one of two possible functions, depending upon which method the browser supports for adding/attaching events, or an empty function if neither is supported. All modern browsers (from Firefox 1, IE 5, etc.) support one or the other or both. So if the browser supports addEventListener, it will use that, otherwise, it is most likely IE, but whatever it is, it will use attachEvent if available in it. Legacy browsers will not run the code, and don't support iframe anyway. This is done one time as the code loads, so after that, no branching is required. The method a browser uses to do this cannot change once the page has loaded, so no need to branch each time this type of thing is needed.

That should answer your questions, but if you have more on that or anything else, feel free to ask. Here's the updated code, fulfilling what I now believe to be your requirements. Notice its configuration area at the end:


(function(){
var overRate, indRate, frame, i, pages = [], attach = (function(){
return window.addEventListener? function(el, ev, f){el.addEventListener(ev, f, false);} :
window.attachEvent? function(el, ev, f){el.attachEvent('on' + ev, f)} : function(){return;};
})();

function updateFrame(){
if (++i < pages.length){
setTimeout(function(){frame.src = pages[i % pages.length];}, indRate * 1000);
}
}

function load(init){
if(init !== null){
frame = document.getElementById('iFrame');
attach(frame, 'load', updateFrame);
}
i = 0;
frame.src = pages[0];
setTimeout(function(){load(null);}, overRate * 1000);
};

attach(window, 'load', load);

//Configure Rates:
overRate = 60; //seconds between over all cycles
indRate = 5; //seconds between individual iframe page changes
//Configure Pages:
pages[0] = "http://www.dynamicdrive.com";
pages[1] = "http://www.bing.com";
pages[2] = "http://www.ask.com";
pages[3] = "http://www.altavista.com";
})();

The rest of the page has not changed. Except you must now remove:


<meta http-equiv="refresh" content="60">

But unless required for some other code, you may also remove the highlighted:


<iframe id="iFrame" src="about:blank" width="100%"
height="100%" name="youriframe" frameborder="1" vspace="0" hspace="0"
marginwidth="0" marginheight="0" scrolling="yes" noresize>
</iframe>

dukevn
12-09-2009, 05:50 PM
This:


(function(){...})()

usually with an appropriate terminus at the end (, or ;) depending upon where it appears in the code, unless as the last property/item in a literal object or array, is the self executing anonymous function. It is used twice in the code. First as a container/wrapper to limit the scope of the code. It makes the code entirely private, so as that its variable and function names cannot conflict with any other code you may add to the page. Second as a function to return one of two possible functions, depending upon which method the browser supports for adding/attaching events, or an empty function if neither is supported. All modern browsers (from Firefox 1, IE 5, etc.) support one or the other or both. So if the browser supports addEventListener, it will use that, otherwise, it is most likely IE, but whatever it is, it will use attachEvent if available in it. Legacy browsers will not run the code, and don't support iframe anyway. This is done one time as the code loads, so after that, no branching is required. The method a browser uses to do this cannot change once the page has loaded, so no need to branch each time this type of thing is needed.
Thanks for your excellent explanation. So
(function(){...})() is for private part (so if there is no other codes, or if I am not afraid of names/variables conflict, then I do not need it); and the attach part is to make the code works cross-browsers.
That should answer your questions, but if you have more on that or anything else, feel free to ask. Here's the updated code, fulfilling what I now believe to be your requirements. Notice its configuration area at the end:
...
You are superb as always, John. Thank you very much, the code works just fine. Now I have another question (not really related to the original question, so if I am doing something wrong, please let me know, I can create new thread for it), if you do not mind: how do I update the page title
<title>Refesh and Loop</title>with the title of any page in the iframe?

Thanks,

D.

16vminimike
06-08-2012, 01:45 PM
Its an old thread yes but its just what I've been looking for except one thing.

How can you get it to delay for a few seconds from loading to switching to the next iframe?

jscheuer1
06-08-2012, 02:42 PM
Isn't that the indRate?

16vminimike
06-08-2012, 02:45 PM
Hi john, firstly many thanks for your prompt reply to an old thread.

Pleae excuse my ignorance, but by increasing the indRate, will that increase the delay before displaying the frame? I'm very new to JS :S

Mike.

jscheuer1
06-08-2012, 05:55 PM
I didn't understand at first what you were after. I just read your other thread though now and I think I see. Are these pages on the same domain as the iframe? If so and if their load or if there's some other event that signifies they're ready, we can use that. If not, we would just have to wait an arbitrary amount of time and hope it's enough.

So, are they on the same domain as the page with the iframe?

16vminimike
06-11-2012, 09:24 AM
yes sorry i did start another thread, I should point it to this one to save confusion.

A little more detail....

This project is for a client who wants a big screen in his sales office that rotates sales reports over xx minutes. Strapped to the back of the screen is a little Raspberry Pi which is on the same network as the report server and just serves this page with this javascript we are discussing.

The requirements have changed since I last posted in that he now wants just the next report to preload rather than all of them at the same time as its placing too much load on the report server.

So essentially, this page needs a list of reports which it'll start by loading the first report and show onscreen, while this report is displaying for example 10 mins, the next report has been generated and is now waiting to be displayed in a hidden div/iframe etc. Then once this report is being displayed the next report is being generated and is now waiting in the first div/iframe - so there are just two divs/iframes that just switch between eachother.

Any help would be gratefully appreciated!

Mike.

jscheuer1
06-11-2012, 01:31 PM
Might need a little tweaking, but this is the general idea:


<!DOCTYPE html>
<html>
<head>
<title>Refesh and Loop w/preload</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
html, body {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.loader {
visibility: hidden;
position: absolute;
top: -100%;
left -100%;
}
iframe {
border-width: 0;
overflow: auto;
}
</style>
</head>
<body>
<iframe id="iFrame" src="http://www.dynamicdrive.com/" width="100%"
height="100%" frameborder="0" vspace="0" hspace="0"
marginwidth="0" marginheight="0" scrolling="auto" noresize>
</iframe>
<iframe class="loader" id="iFrame2" src="about:blank" width="100%"
height="100%" frameborder="0" vspace="0" hspace="0"
marginwidth="0" marginheight="0" scrolling="auto" noresize>
</iframe>
<script type="text/javascript">
(function(){
//Configure Rate:
var rate = 10; //minutes between iframe page changes
//Configure Pages:
var pages = [];
pages[0] = "http://www.dynamicdrive.com/";
pages[1] = "http://www.bing.com/";
pages[2] = "http://www.ask.com/";
pages[3] = "http://www.altavista.com/";

var frames = [document.getElementById('iFrame'), document.getElementById('iFrame2')], page = 1;
setTimeout(function(){frames[1].src = pages[1];}, 5000);

function update(){
if(frames[1].className === 'loader'){
frames[1].className = '';
frames[0].className = 'loader';
frames[0].src = pages[++page %pages.length];
} else {
frames[0].className = '';
frames[1].className = 'loader';
frames[1].src = pages[++page %pages.length];
}
}
setInterval(update, rate * 1000 * 60);
})();
</script>
</body>
</html>

Since there's no way to preload the first page the first time, simply set the first iframe's src attribute to it.

One tweak I have in mind is dynamically setting a query variable for each page every time it's preloaded so it cannot reload from cache. I can't do that with the search engine examples because some have strict policies on how query strings are interpreted.

Your client's report pages would probably work fine with this concept, and it might be required, but how it's applied would depend upon whether or not they already have query parameters in their URL's. What's a typical report URL look like?

The other is how long to wait after the page first loads, to load the next page. I figured 5 seconds would be enough:


setTimeout(function(){frames[1].src = pages[1];}, 5000);

But since you're waiting 10 minutes between pages, it could be longer.

Slightly related - the way it is now, since after the initial loading, whenever a page is displayed, it has already loaded, that's when the next page begins to load. But that means it will be 10 minutes out of date by the time it's shown. That can be tightened up by delaying it's load to - say 1 minute before it will be seen. Let me know on that one, if it's important.

16vminimike
06-12-2012, 10:23 AM
Wow you star! I did some further tweaking to allow me to load the reports required from a little database so this one page can now provide reports for multiple clients which I couldn't of done without your help so I cant thank you enough.

I did try and use the Thanks button on the thread but it spits back a list of deprecated errors:

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 55

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 107

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 111

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 119

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 130

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 134

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 142

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 211

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/init.php on line 389

Deprecated: Assigning the return value of new by reference is deprecated in /home/gchiang/public_html/forums/includes/class_core.php on line 2552

keyboard
06-12-2012, 10:30 AM
Yes, this is a known problem (ddadmin recently upgraded to a newer version of vbulletin) and it's being looked at (I think). The thanks button still works, just ignore the warning.

P.s. They're warnings, not errors