?
Solved

How can I make window.onload work after <body onload function

Posted on 2009-04-22
7
Medium Priority
?
695 Views
Last Modified: 2012-05-06
My HTML page has two functions that work beautifully on their own but when put together the second one isn't working. I've tried calling the second function from within the first but it doesn't work.

The first function gets and displays RSS feeds. In summary it works like this...
<script type="text/javascript">
function getFeed(feed,div_id)
{
//...
}

function getFeeds()
{
  getFeed("http://feeds.reuters.com/reuters/worldNews","source")
  // getFeed is called several times with different feeds
}
</script>
</head>
<body onload="getFeeds()">
<div id='source'>
</div>

The second function grabs that feed before it is displayed, and processes it so that it only displays one image even if the feed contains several.
You can see this original function init() in its successful form at the bottom of the snippet.

The problem seems to be that image-processing init() function is triggered by window.onload=init; and the RSS function is triggered by <body onload="getFeeds()">, and they're not working together in the correct order. I've tried calling init() from various places but none seem to work. The displayed output won't limit to one image. Several images are displaying.

You'll see in the snippet that in my latest attempt I have inserted window.onload=init; at the end of function getFeeds(), but it doesn't seem to be triggering it.
<script type="text/javascript">
var puthere = new Array();
var count1 = 0;
var count2 = 0;
 
function getFeed(feed,div_id) 
{
  if(feed.toString().indexOf('http')!=-1)
  {
  puthere[count1]=div_id;
  count1++;
  var newScript = document.createElement('script');
  newScript.type = 'text/javascript';
  newScript.src = 'http://pipes.yahoo.com/pipes/pipe.run?_id=602dddd329a9ec7139334702e9785a76&_render=json&_callback=piper&feed='+feed;
  document.getElementsByTagName("head")[0].appendChild(newScript);
  }
}
 
function piper(feed) 
{
  var tmp='';
  for (var i=0;
  i<feed.value.items.length; i++) 
  {
    tmp+='<a href="'+feed.value.items[i].link+'">';
    tmp+=feed.value.items[i].title+'</a><br>';
    if (feed.value.items[i].description) 
    {
      tmp+=feed.value.items[i].description;
    }
    tmp+='<hr>';
  }
  document.getElementById(puthere[count2]).innerHTML=tmp;
  count2++;
}
 
function getFeeds()
{
  getFeed("http://feeds.reuters.com/reuters/worldNews","source")
  // getFeed is called several times with different feeds
  // ??????????????????????? I have tried unsuccessfully to run init() from here?????????????????????
  window.onload=init;
}
 
function init()
{
// see below
}
</script>
</head>
<body onload="getFeeds()">
<div id="thepg">
<div id="showonepic">
<div id='source'>
</div>
</div>
 
</div>
</body>
</html>
 
********************0riginal********************
<script type="text/javascript">
//"schedule" the function init to be executed once the document loads
window.onload=init;
 
function init()
{
	// attempt to get an array of references to the divs containing the images
	var container = document.getElementsByTagName("div");
	// make sure we have at least one div returned
	if (container.length)
	{
	 	for( var j = 0, outerlimit = container.length; j < outerlimit; ++j)
		{
 
			var elemID = document.getElementsByTagName("div")[j].id;
			if (elemID == "showonepic") 
			{
				var cont_images = container[j].getElementsByTagName("img");
 
				//make sure that at least one img element was returned
				if (cont_images.length)
				{
					//iterate through the list
					for( var i = 0, limit = cont_images.length; i < limit; ++i )
					{
						//"remove" every single image from the screen
						cont_images[i].style.display='none';
					}
 
					// do the resizing while hidden            
 
					var new_width = 200;
					var imagetoprocess = cont_images[0];
					var old_width = imagetoprocess.width;
					var old_height = imagetoprocess.height;
					imagetoprocess.width = new_width;
					imagetoprocess.height = Math.round(old_height * new_width / old_width);
 
					//now "activate" ony the first image on the list
 
					cont_images[0].style.display="";
				}
			}
		}
	}
}
// -->
</script>

Open in new window

0
Comment
Question by:NEILPH
  • 4
  • 3
7 Comments
 
LVL 41

Expert Comment

by:HonorGod
ID: 24211005
What you need to know is that it is possible for more than 1 function to be executed as part of the onload processing.  The way to do this is:

- Save the current "onload" value (which might be null)
- Define your own onload routine that
  - performs your onload processing, and
  - if necessary calls the previously defined onload function.

However, you could certainly have your initialization function called last.  For example:


var oldOnload = window.onload
window.onload = function() {
  if ( oldOnload ) {
    oldOnload()
  }
  myInit()
}

Open in new window

0
 

Author Comment

by:NEILPH
ID: 24211634
I successfully called init() from getFeeds() as in the snippet pseudocode below.

It appear that init() is working. I put an alert(elemID) in and it showed all the <div ids correctly.

But <div id="showonepic"> is still showing several images when it shouldn't. So the problem must lie elsewhere.

If you wait I'll do some more exploring to see if I can spot more about the problem and discuss it with you. Otherwise, would you prefer me to close this question and allot points?

I've just retested an earlier version of the page that didn't have the the GetFeeds() and nested divs (i.e. <div id="showonepic"><div id='source'></div></div> but simply had the unnested <div id="showonepic"></div>). It works. First it shows all the images and then after a few seconds it removes the unwanted ones. (I don't mind this delay.)

I can't see how the getFeeds() and <div id='source'></ are blocking this.

Very odd.





function getFeed(feed,div_id) 
 
function getFeeds()
{
  getFeed("http://feeds.reuters.com/reuters/worldNews","source")
  window.onload=init;
}
 
function init()
{
// allow only the first image to show
}
</script>
</head>
 
<body onload="getFeeds()">

Open in new window

0
 

Author Comment

by:NEILPH
ID: 24212077

I think I'm starting to see why the number of images displaying isn't successfully reducing to just one in <div id="showonepic"> but I need expert help.

When I run the HTML page containing the code in the snippet below, the following happens in this order...

1. function init() works perfectly for the hard-coded <div id="showonepic"><h1><u>Northland Homes for Sale</u></h1><div id='north_source'>
It correctly reduces the number of images that display there from 4 to one.
(It first displays all 4 images and then after about 5 seconds it removes the last 3. This sluggish speed is fine with me.)

2. Immediately the above action is completed, the contents of <div id="showonepic"><h1><u>Northland properties</u></h1><div id='j_source'></div></div> are displayed. These are
generated by getFeed("http://feeds.realestate.co.nz/residential/all/northland-central/rss2.xml","j_source". The 4 images DO NOT REDUCE TO JUST ONE. This is the problem.

My conclusion is the init() function [that removes some images] is running BEFORE any content is generated by getFeed() and therefore is too early to remove images from it. This despite the fact that I have placed init() at the end of getFeeds()

I reckon that init() needs to run for each RSS feed from somewhere within getFeed() or getFeeds(). It's beyond my skill to figure out where. Can you help?

By the way, I only created the hard-coded content to do this debugging. In the final project all the content will be generated via getFeed() instances.
<script type="text/javascript">
var puthere = new Array();
var count1 = 0;
var count2 = 0;
function getFeed(feed,div_id) {
if(feed.toString().indexOf('http')!=-1){
puthere[count1]=div_id;
count1++;
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = 'http://pipes.yahoo.com/pipes/pipe.run?_id=602dddd329a9ec7139334702e9785a76&_render=json&_callback=piper&feed='+feed;
document.getElementsByTagName("head")[0].appendChild(newScript);
}
}
 
function piper(feed) {
var tmp='';
for (var i=0; i<feed.value.items.length; i++) {
tmp+='<a href="'+feed.value.items[i].link+'">';
tmp+=feed.value.items[i].title+'</a><br>';
if (feed.value.items[i].description) {
tmp+=feed.value.items[i].description;
}
tmp+='<hr>';
}
document.getElementById(puthere[count2]).innerHTML=tmp;
count2++;
}
 
function getFeeds()
{
getFeed("http://feeds.realestate.co.nz/residential/all/northland-central/rss2.xml","j_source")
// and many other getFeed instances
init()
}
 
//"schedule" the function init to be executed once the document loads
//window.onload=init;
 
function init()
{
	// attempt to get an array of references to the divs containing the images
	var container = document.getElementsByTagName("div");
	// make sure we have at least one div returned
	if (container.length)
	{
	 	for( var j = 0, outerlimit = container.length; j < outerlimit; ++j)
		{
 
			var elemID = document.getElementsByTagName("div")[j].id;
			if (elemID == "showonepic") 
			{
				var cont_images = container[j].getElementsByTagName("img");
 
				//make sure that at least one img element was returned
				if (cont_images.length)
				{
					//iterate through the list
					for( var i = 0, limit = cont_images.length; i < limit; ++i )
					{
						//"remove" every single image from the screen
						cont_images[i].style.display='none';
					}
 
					// do the resizing while hidden            
 
					var new_width = 200;
					var imagetoprocess = cont_images[0];
					var old_width = imagetoprocess.width;
					var old_height = imagetoprocess.height;
					imagetoprocess.width = new_width;
					imagetoprocess.height = Math.round(old_height * new_width / old_width);
 
					//now "activate" ony the first image on the list
 
					cont_images[0].style.display="";
				}
			}
		}
	}
}
// -->
</script>
 
 
</head>
<body onload="getFeeds()">
<div id="thepg">
 
<div id="showonepic"><h1><u>Northland properties</u></h1>
<div id='j_source'></div>
</div>
 
<div id="showonepic">
<h1><u>Northland Homes for Sale</u></h1>
<div id='north_source'>
<p>http://www.realestate.co.nz/residential/all/northland-central</p>
 
<p> 04/19/2009 03:01 AM </p>
      <p><b>Northland, Wellington City - The Grand Old Lady</b></p>
      <p>Tender.  1900's charm, exposed floor boards, sash windows, ripe for restoration or rental.  Currently configured as 2 bedroom flat and 1 bedroom flat, both with separate bathroom and kitchen.  Create a home or maximise a rental proposition.  Elevated positioning, City fringe location.  RV $455,000, Rates $1,895.15 (2008/2009), House 140m2, Site 506m2.  For Sale By Tender closing Thursday, 14th May 2009 at 3pm at Gillies and Mark Real Estate, 75 Taranaki Street, Wellington.
Open Home: 17/05/2009 from 12:00 p.m. to 12:30 p.m.<br /><img src="http://images3.realestate.co.nz/edi/OSLglen001/photos/CIT10820-1.jpg" width="320" height="240" alt="" /><img src="http://feeds.realestate.co.nz/residential/all/northland-central?view=1047328" /></p>
    
<p> 04/03/2009 02:41 AM </p>
      <p><b>Northland, Wellington City - LIVE IN OR RENT OUT!</b></p>
      <p>Buyer enquiry welcome from $450,000. Super sunny home in popular Northland. This 3 bedroom 1980s home has a lovely outlook to the hills and Karori. Definitely room to add your touch to the decor and possibly add value. Bonus of being Wellington College Zoned. www.tommys.co.nz Ref: T7486<br /><img src="http://images3.realestate.co.nz/edi/vcltomm001/photos/T7486-1.jpg" width="320" height="240" alt="" /><img src="http://feeds.realestate.co.nz/residential/all/northland-central?view=1037714" /></p>
    
<p> 03/26/2009 06:04 AM </p>
      <p><b>Northland, Wellington City - Romantic Northland Bungalow</b></p>
      <p>Once in a while the perfect home for singles and couples comes to the market  no. 53 is just that. Located in a highly sought after street and sited for all day sun and easy access, this very attractive home will be hard to beat. Well maintained, it boasts 2 spacious bedrooms, separate lounge and dining rooms, practical kitchen and the bonus of a 3rd bedroom or study. Breakfast on the east facing deck and enjoy a wine in the evening on the veranda. Single garage. www.open2view.com/200798 R.V. $550,000<br /><img src="http://images3.realestate.co.nz/edi/LEADERS001/photos/LDR42977-1.jpg" width="320" height="240" alt="" /><img src="http://feeds.realestate.co.nz/residential/all/northland-central?view=1031684" /></p>
    
<p> 03/23/2009 02:38 PM </p>
      <p><b>Northland, Wellington City - Estate Auction</b></p>
      <p>A once grand home with fantastic harbour and city views and first time on the market in 100 years!  Terrific potential for those with vision who are prepared to restore this two  flat property into its original condition.  Options to be a home and  income or investment.  Built in 1908 using quality Matai timber on a prime site of 759m with dual access.  It is located in a sought after street close to transport and Victoria University.  Your efforts will be well rewarded!  Rating Valuation $520,000.
AUCTION ON SITE, 23rd APRIL 2009 AT 12 NOON.<br /><img src="http://images3.realestate.co.nz/edi/_7303/photos/15seaview-1.jpg" width="320" height="240" alt="" /><img src="http://feeds.realestate.co.nz/residential/all/northland-central?view=1029200" /></p>
</div>
</div>
 
</div>
</body>
</html>

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 41

Accepted Solution

by:
HonorGod earned 2000 total points
ID: 24213790
getfeed retrieves additional code from pipes.yahoo.com, and executes pipes.run with some parameters.

I surmise that this code includes some Ajax (Asynchronous JavaScript And XML) code that connects to a back end application, and which some time later receives a callback from this back end server code.

So, I think that your init() completes before this callback occurs.

You may want to have your init() performed after a delay ... say perhaps 1/2, or 3/4 seconds.  This could be done using:

setTimeout( 'init()', 500 )                     // 500 milliseconds = 0.5 seconds
0
 

Author Comment

by:NEILPH
ID: 24221603
That worked but not until I increased the timeout to a huge 2000. And even then it is temperamental. Sometimes...
a. nothing appears, text or images
b. the text and 4 images appear but it doesn't reduce to just one image
c.     "                                "         - and after a short while it correctly reduces to one image
d. it appears immediately as the text and just one image; [the dream result].

If I refresh the page the correct result is shown, (c. or preferably, and usually, d.)

I suspect the above results may be affected by caching, although they do involve separate browser sessions.

So, your surmise about Ajax looks to be right. I do recall that a month ago when I first started using Yahoo Pipes I had to tweak things [with advice from Expert Exchange] to stop multiple outputs overwriting each other.

It would be nice if the functioning were more reliable. I did try a timeout of 5000, which seemed OK.

Have you any comments? Then I'll close and allot the points.  Thanks for your help.
0
 
LVL 41

Expert Comment

by:HonorGod
ID: 24224129
Sorry, I haven't used the Yahoo toolkit, so that is an area with which I am unfamiliar.

There are probably some experts that are much more familiar with that toolkit, and its tendencies, and foibles.
0
 
LVL 41

Expert Comment

by:HonorGod
ID: 24231931
Thanks for the grade & points.

Good luck & have a great day.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When it comes to write a Context Sensitive Help (an online help that is obtained from a specific point in state of software to provide help with that state) ,  first we need to make the file that contains all topics, which are given exclusive IDs. …
Q&A with Course Creator, Mark Lassoff, on the importance of HTML5 in the career of a modern-day developer.
In this tutorial viewers will learn how to embed videos in a webpage using HTML5. Ensure your DOCTYPE declaration is set to HTML5: "<!DOCTYPE html>": Use the <video> tag to insert a video. Define the src as the URL of your video; this is similar to …
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question