Link to home
Start Free TrialLog in
Avatar of NEILPH
NEILPHFlag for New Zealand

asked on

Inner HTML IE malfunction

I'm using innerHTML to put Yahoo Pipes feeds into individual <div>s on my webpage.

It works in Firefox but in IE6,7,8 the feeds often go into the wrong divs. If I refresh the page they often change. You can see my test page online at http://www.isc.co.nz/feedblop.htm. Also, at http://www.isc.co.nz/feeddlop.htm I have included an alert box, which makes even Firefox get <div> confusion.

They should appear in this same order as the captions: Reuters International, US and UK [usually identified by London headlines], New Zealand news, business and finally sport.

Researching via Google I've found several statements [even at MSDN] that IE can get confused using .innerHTML and send each output to the incorrect <div>. That describes my problem exactly. I've tried 2 of the suggested solutions without success: making the <div> names very different, and using a placeholder [see bottom of snippet]. Maybe I've executed them incorrectly.

Can you help?
<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","a_source")
getFeed("http://feeds.reuters.com/reuters/domesticNews","b_source")
getFeed("http://feeds.reuters.com/reuters/UKdomesticNews","c_source")
getFeed("http://tvnz.co.nz/content/1323502/rss_20_skin.xml","g_source")
getFeed("http://tvnz.co.nz/content/1323589/rss_20_skin.xml","h_source")
getFeed("http://tvnz.co.nz/content/455321/rss_20_skin.xml","i_source")
 
}
 
</script>
 
</head>
<body>
<h1><u>a Reuters International</u></h1>
<div id='a_source'></div>
 
<h1><u>b Reuters US</u></h1>
<div id='b_source'></div>
 
<h1><u>c Reuters UK</u></h1>
<div id='c_source'></div>
 
<h1><u>g NZ National</u></h1>
<div id='g_source'></div>
 
<h1><u>h NZ Business</u></h1>
<div id='h_source'></div>
 
<h1><u>i NZ Sport</u></h1>
<div id='i_source'></div>
 
*******attempted variation using a placeholder*******
 
ge = document.getElementById(puthere[count2]);
ge.style.display = "block";
ge.innerHTML = tmp;
count2++;

Open in new window

Avatar of SadafRasheed
SadafRasheed
Flag of Pakistan image

i havent run your script but i would suggest use of jquery... and replace line number 25 of your code with

$('#'+puthere[count2]).html(tmp);

Jquery's html function works on every browser
Avatar of NEILPH

ASKER

Hi SadafRasheed. Sorry to be slow getting back to you. A lot of work landed in front of me.

I'm maybe the only developer who'd never heard of jquery but as you suggested, I've given it a go; see http://www.isc.co.nz/feedjlop.htm.

Maybe I did something wrong but it doesn't work [in IE8]. It throws this error at the jquery line...
Message: Object expected
Line: 77
Char: 1
Code: 0
URI: http://www.isc.co.nz/feedjlop.htm

I think I've set that page up correctly. I uploaded jquery-1.3.2.min.js to the same folder as http://www.isc.co.nz/feedjlop.htm and as you can see if you look at the source, I followed their instructions and placed <script type="text/javascript" src="jquery.js"></script> in the <head> just above the normal <script...> line, and then I used your line instead of mine.


I'm not sure whether to make a policy decision to use jquery. It looks like it might be particularly good for JSON, which I use. On the other hand, how many experts at E-Exchange know it. It might severely reduce E-Exchange as my support resource.
You have not placed jquery.js in the path specified. You have given the following path

http://www.isc.co.nz/jquery.js

but if you open it up in browser, you'll get 404.

Go to the following url and download jquery-1.3.2.min.js file.

http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.3.2.min.js&downloadBtn=


I have seen a LOT of resources for JQuery, lots of plugins, lots of help, even lots of video tutorials for beginners. I am 100% sure EE also have many JQuery experts. You can post a questions here in EE, asking how many jquery experts are there and then depending on the response you get, you can decide for yourself.
I am, by no means, an expert in javascript but i never had any problem with jquery,, i think every one can use it easily.
Avatar of NEILPH

ASKER

I hadn't noticed that the script reference suggested by the jquery site was to http://www.isc.co.nz/jquery.js. I've changed it to jquery-1.3.2.min.js and it works. See http://www.isc.co.nz/feedjlop.htm.

Except that unfortunately it doesn't work. Looking at that page in my IE8 it still puts some of the outputs into the wrong <div>, e.g. Reuters UK incorrectly in NZ sport.

I know that these feeds are OK. http://www.isc.co.nz/feedjlop.htm renders correctly in FireFox 3.5.

I've since noticed that there is a jquery zone at E-E as a subzone of javascript.

Avatar of NEILPH

ASKER

SadafRasheed

Can you give any more help to make this work or should I close teh question?
hi NEILPH,,

i dont know the reason behind this but when i added a div around the tmp text it fixed the problem in ie8 as well.

Try this...
function piper(feed) {
var tmp='';
for (var i=0; i<feed.value.items.length; i++) {
tmp+='<div><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></div>';
}
document.getElementById(puthere[count2]).innerHTML=tmp;
count2++;
} 

Open in new window

Avatar of NEILPH

ASKER

Hi again SadafRasheed

Unfortunately, using your latest code it is still not working in IE8, some feeds are in the wrong <div>; see http://www.isc.co.nz/feeddiv.htm.

However, when I add an alert at the start of...
function getFeed(feed,div_id) {
alert('feed: ' + feed + ' div: ' + div_id)

...as demonstrated at http://www.isc.co.nz/feeddivalert.htm, it appears to work. This suggests that slowing things down is beneficial. I think this hints at a solution, as you'll see if you read the snippet, which details how Experts robinu and sunithnair helped me develop this code. We found that Yahoo Pipes was too fast. You'll see their solutions. I chose sunithnair's solution of using an array. Maybe the answer here is something similar.

Another thing I've noticed is that when instead I put  the alert('feed: ' + tmp + ' div: ' + puthere) near the end of function piper(feed), FireFox appears to render each feed immediately after I click the alert box. IE appears to render all the feeds in one go after I've clicked the final alert box. This seems to me to be a place where things could get confused in IE.

I'll continue working on this but I would value your further input. My javascript skills are not strong.

Thanks.   [By the way, I guess I might as well remove the jquery link.]
********************************************************************************************************************
Author Comment
Author: NEILPH </M_4362456.html> Date: 02/24/2009 - 04:53PM NZDT
 
Robinu, I've tried to debug your solution to see why it incorrectly puts
both outputs into div 'b_source', with the second output overwriting the
first one.
 
I placed alert(puthere); in function getFeed(feed,div_id) and ran the
page. Two alerts appeared, the first showing 'a_source' and the second
showing 'b_source'.
 
However when I placed alert(puthere); into function piper(feed,puthere)
the two alerts appearances both showed 'b_source'. This looks to be the
source of the problem. Any suggestions?
 
My current code is in the snippet below...
1:	<script type="text/javascript">        
2:	var puthere;
3:	function getFeed(feed,div_id) {
4:	 puthere=div_id;
5:	 var newScript = document.createElement('script');
6:	 newScript.type = 'text/javascript';
7:	 newScript.src =
'http://pipes.yahoo.com/pipes/9oyONQzA2xGOkM4FqGIyXQ/run?&_render=json&_callback=piper&feed='+feed;
 
8:	 document.getElementsByTagName("head")[0].appendChild(newScript);
9:	}
10:	function piper(feed) {
11:	 alert(puthere);
12:	 var tmp='';
13:	 for (var i=0; i<feed.value.items.length; i++) {
14:	   tmp+='<a href="'+feed.value.items[i].link+'">';
15:	   tmp+=feed.value.items[i].title+'</a><br>';
16:	   if (feed.value.items[i].description) {
17:	     tmp+=feed.value.items[i].description;
18:	   }
19:	   tmp+='<hr>';
20:	 }
21:	 document.getElementById(puthere).innerHTML=tmp;
22:	}      
23:	</script>  
24:	</head>
25:	<body
onLoad='getFeed("http://tvnz.co.nz/content/1323589/rss_20_skin.xml","a_source");
getFeed("http://feeds.reuters.com/reuters/worldNews","b_source");'>  
26:	<div id='a_source'>
27:	</div>  
28:	<div id='b_source'>
29:	</div>
**********************************************************************************************************
Expert Comment
Author: robinu </M_3572319.html> Date: 02/24/2009 - 07:27PM NZDT
Ahh, I didn't think of that. The two getFeed() function run so 'fast'
after each other the div gets overwritten,
before the contents is placed by the yahoo function.
Try the attached code. Instead of giving the div id of where the contect
is to placed, you give it the function
name for callback. In that callback function you decide which to use.
 
Will this work for you?
1:	<script type="text/javascript">        
2:	function getFeed(feed,callback) {
3:	 var newScript = document.createElement('script');
4:	 newScript.type = 'text/javascript';
5:	 newScript.src =
'http://pipes.yahoo.com/pipes/9oyONQzA2xGOkM4FqGIyXQ/run?&_render=json&_callback='+callback+'&feed='+feed;
 
6:	 document.getElementsByTagName("head")[0].appendChild(newScript);
7:	}
8:	function piper1(feed) {
9:	  piper(feed,'a_source');
10:	}
11:	function piper2(feed) {
12:	  piper(feed,'b_source');
13:	}
14:	function piper(feed,puthere) {
15:	 alert(puthere);
16:	 var tmp='';
17:	 for (var i=0; i<feed.value.items.length; i++) {
18:	   tmp+='<a href="'+feed.value.items[i].link+'">';
19:	   tmp+=feed.value.items[i].title+'</a><br>';
20:	   if (feed.value.items[i].description) {
21:	     tmp+=feed.value.items[i].description;
22:	   }
23:	   tmp+='<hr>';
24:	 }
25:	 document.getElementById(puthere).innerHTML=tmp;
26:	}      
27:	</script>
28:	</head>
29:	<body
onLoad='getFeed("http://tvnz.co.nz/content/1323589/rss_20_skin.xml","piper1");
getFeed("http://feeds.reuters.com/reuters/worldNews","piper2");'>
30:	
31:	<div id='a_source' style="border:1px solid #f00;">
32:	</div>
33:	
34:	<div id='b_source' style="border:1px solid #00f;">
35:	</div>
**********************************************************************************************************
Expert Comment
Author: sunithnair </M_4780406.html> Date: 02/24/2009 - 07:40PM NZDT
Check this one out. The problem is because the callback happens after a
certain amount of time so you need to save the div element ids in an array.
1:	<html>
2:	<head>
3:	<script type="text/javascript">        
4:	var puthere = new Array();
5:	var count1 = 0;
6:	var count2 = 0;
7:	function getFeed(feed,div_id) {
8:	 puthere[count1]=div_id;
9:	 count1++;
10:	 var newScript = document.createElement('script');
11:	 newScript.type = 'text/javascript';
12:	 newScript.src =
'http://pipes.yahoo.com/pipes/9oyONQzA2xGOkM4FqGIyXQ/run?&_render=json&_callback=piper&feed='+feed;
 
13:	 document.getElementsByTagName("head")[0].appendChild(newScript);
14:	}
15:	function piper(feed) {
16:	 var tmp='';
17:	 for (var i=0; i<feed.value.items.length; i++) {
18:	   tmp+='<a href="'+feed.value.items[i].link+'">';
19:	   tmp+=feed.value.items[i].title+'</a><br>';
20:	   if (feed.value.items[i].description) {
21:	     tmp+=feed.value.items[i].description;
22:	   }
23:	   tmp+='<hr>';
24:	 }
25:	 document.getElementById(puthere[count2]).innerHTML=tmp;
26:	 count2++;
27:	}      
28:	</script>
29:	</head>
30:	<body
onLoad='getFeed("http://tvnz.co.nz/content/1323589/rss_20_skin.xml","a_source");
getFeed("http://feeds.reuters.com/reuters/worldNews","b_source");'>
31:	
32:	<div id='a_source'>
33:	</div>
34:	
35:	<div id='b_source'>
36:	</div>
37:	</html>
********************************************************************************************************
Author Comment
Author: NEILPH </M_4362456.html> Date: 02/25/2009 - 04:04PM NZDT
Robinu and Sunithnair
 
Both your solutions work fine so now I have a dilemma alloting points.
This kind of solution originally came from Robinu so you deserve top
marks. However, Sunithnair's final code looks slightly simpler with
multiple array vars versus multiple piper functions. This could be an
issue in my final app where I expect to have 15 RSS feeds. And - maybe
I'm imagining it - but perhaps Sunithnair's runs slightly faster.
 
I'd like to give you both 500 but if I can't would you both be happy if
I split it 250-250.
 
By the way, these solutions work just as well if instead of <body
onload> I  put the calls as functions in the header, see snippet. This
seems cleaner to me. Or do you think it is a bad idea?
 
Thanks.
1:	Robinu  
2:	getFeed("http://tvnz.co.nz/content/1323589/rss_20_skin.xml","piper1")  
3:	getFeed("http://feeds.reuters.com/reuters/worldNews","piper2")      
4:	</script>
5:	</head>    
6:	Sunithnair  
7:
getFeed("http://tvnz.co.nz/content/1323589/rss_20_skin.xml","a_source")  
8:	getFeed("http://feeds.reuters.com/reuters/worldNews","b_source")
9:	</script>
10:	</head>
 
Accepted Solution
Author: sunithnair </M_4780406.html> Date: 02/25/2009 - 07:29PM NZDT
I have no issue with the points. It sould be better if you put in the
onload because we can make sure that all the divs have been loaded
before the rss feeds are loaded. You can create a function in which you
can call the getFeed function and call this function in onload like this
1:	<script language='javascript'>
2:	function getFeeds()
3:	{
4:
getFeed("http://tvnz.co.nz/content/1323589/rss_20_skin.xml","a_source")  
5:	getFeed("http://feeds.reuters.com/reuters/worldNews","b_source")
6:	}
7:	</script>
8:	<body onload="getFeeds()">
 
Assisted Solution
Author: robinu </M_3572319.html> Date: 02/25/2009 - 07:38PM NZDT
The points split is fine with me too. And sunithair is right about the
placement of the functions in your page.
Thanks.
© Copyright Experts Exchange LLC 2009.

Open in new window

Avatar of NEILPH

ASKER

SadafRasheed

You didn't respond to my last comment and I have been diverted by other work. As a result this Question has remained open. I'd like to close it now without awarding points if that's alright with you.

I have just tested a variation based on the code by Expert robinu that is in the snippet which is contained in my previous last comment. It works in Internet Explorer, i.e. the feeds don't go into the wrong <div>.

I think the difference is that the approach I was discussing with you uses an array. The robinu approach doesn't. I think that maybe Internet Explorer wasn't coping with the array. Perhaps it doesn't allocate enough memory for an array AND feed manipulation.

I look forward to hearing from you.
ASKER CERTIFIED SOLUTION
Avatar of SadafRasheed
SadafRasheed
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial