homepage Welcome to WebmasterWorld Guest from 54.226.180.223
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
document.images cross browser problems
simple script fails due to array differences
Hester




msg:4340962
 8:51 pm on Jul 18, 2011 (gmt 0)

I have written a small script to display all the titles of images on a page underneath the images. The core of the script is below:

document.getElementById('table'+row+'td'+b).innerHTML = document.images[image]['title'];

The ID is a table cell I reference by an incremental name in a loop, such as "table1td6". The variable "image" is used to refer to each image in a row.

It works! But when I tried it in various browsers I was surprised to see differences. Some browsers were putting the title text one table cell too far to the right.

To check my script I entered the following code:

alert('images 0 = ' + document.images[0]['title']);

This should give me the title of the first image on the screen. In the problem browsers it gives the title of an earlier image instead. Clearly there isn't one so it is blank. Whatever image I target, the problem browsers give me a title of a previous image, eg: 1 instead of 2.

My conclusion is that document.images differs by 1 between browsers! Yet I have read on ppk's site that it is part of DOM 0 and is reliable across all browsers. It gives you access to an array of all images on the page. Yet some browsers are clearly starting the array at 1 instead of 0!

What can I do to get round this? Otherwise my script is useless!

Here are the browser results I tested in:

Out by 1:
Firefox 5
Chrome 12
Safari (Windows)

Works as expected:
Opera 11
Internet Explorer 7

 

penders




msg:4340983
 10:18 pm on Jul 18, 2011 (gmt 0)

I've just done a quick test and I get consistent results across all the browsers I've tried: Chrome 10, IE8, Safari (Win), Opera 11.5. (I can't just test FF at the moment). All browsers start from 0 with the first IMG on the page.

There is nothing in the Mozilla docs to suggest otherwise:
https://developer.mozilla.org/en/DOM/document.images

And like you say, this is DOM 0 and should be concrete.

Do you have any HTML errors on your test page? Does your page validate? - This could cause inconsistent behaviour.

What output do you get from the following...?
for (var n=0; n<document.images.length; n++) { 
document.writeln(n + ' - ' + document.images[n]['src']);
}

penders




msg:4340990
 10:31 pm on Jul 18, 2011 (gmt 0)

What can I do to get round this?


You don't need to use
document.images, you can use the NodeList as returned by document.getElementByTagName('img') instead. However, both should return comparable results and if one is broken I suspect the other is too. I would persevere with document.images to see what the underlying cause is.
Hester




msg:4341000
 10:38 pm on Jul 18, 2011 (gmt 0)

Your test code comes up with the path of the first image in Opera. However in Firefox it shows a mysterious geo.yahoo.com image path! OK, time to come clean and say that my code is based around a script that shows me my latest images on Flickr. This is auto-generated so I've no idea what is in the script. Could it be adding a hidden image? (EDIT: yes, one shows up when I list all images using the Web Developer plugin! But not in Opera or IE?)

My page does kinda validate, except for warnings about the script tags and missing table cells generated by them later.

Hester




msg:4341007
 10:46 pm on Jul 18, 2011 (gmt 0)

Got it - using Opera's Dragonfly I can view the HTML generated by the script. There's a hidden SPAN with an IMG in it of size 0, positioned -999ems off the screen! Even so, this should appear in all browsers, surely? And certainly be part of the document.images array.

penders




msg:4341012
 11:03 pm on Jul 18, 2011 (gmt 0)

It would seem that the hidden image that the other script generates is throwing your results off.

NOT TRUE IT SEEMS: Perhaps the additional image is not created in Opera or IE because these browsers do not support some additional feature?! Geo-location?! (That is a wild guess btw! Opera 10.6+ and IE9+ do support geolocation, but IE8 and lower do not.)

- EDIT -

Got it - using Opera's Dragonfly I can view the HTML generated by the script. There's a hidden SPAN with an IMG in it of size 0, positioned -999ems off the screen! Even so, this should appear in all browsers, surely? And certainly be part of the document.images array.


Interesting. Yes, I would have thought it should still be present to the document.images array, it is still part of the DOM after all and Opera's Dragonfly is somehow able to access it. No amount of CSS hiding removes an image for me, all browsers show all my images. I can try adding an image with script...

penders




msg:4341024
 11:43 pm on Jul 18, 2011 (gmt 0)

I can try adding an image with script...


The image still appears for me in the document.images array when generated by script.

I just wonder if the geo.yahoo.com image is being generated after some delay and some other browser quirk is resulting in your script running before/after (depending on browser) this additional image is added to the DOM. So may be it's a timing issue?!

At what stage do you run your script? Can you run your script from a user click ie. a long time after the page has finished loading?

Hester




msg:4341362
 7:31 pm on Jul 19, 2011 (gmt 0)

Yes I think it is a timing issue, or code that only targets certain browsers!

The code is run onload.

I thought of the solution - check for "geo.yahoo.com" in the path of the first image - if it's there, get the next image title instead. I'm not sure how to check for the text in the path - can you help me with the code?

penders




msg:4341377
 7:59 pm on Jul 19, 2011 (gmt 0)

If you're pretty sure that the rogue image always contains "geo.yahoo.com" in the path, then you can search for this in the img src attribute using the indexOf() method.

for (var n=0; n<document.images.length; n++) { 
if (document.images[n]['src'].indexOf('geo.yahoo.com') > -1) {
continue;
}

document.writeln(n + ' - ' + document.images[n]['src']);
}


This checks every image and skips over it if it contains said string. To check just the first image (if you're sure this is reliable) then, in the above loop...

if ((n == 0) && document.images[n]['src'].indexOf('geo.yahoo.com') > -1) {
Hester




msg:4341384
 8:09 pm on Jul 19, 2011 (gmt 0)

Hey thanks, I'll try that. Regarding your first loop, I only ever get one line output from that. Document write stops after the first echo.

Hester




msg:4341397
 8:50 pm on Jul 19, 2011 (gmt 0)

It works! Thank you! I'll PM you a link to the demo when it's live.

One last thing - what else can document.images give you? Can it reveal the date the image was uploaded? That would be very useful.

penders




msg:4341459
 10:54 pm on Jul 19, 2011 (gmt 0)

Glad you got it sorted - thanks for the link - nice one!

Regarding your first loop, I only ever get one line output from that. Document write stops after the first echo.


Were you testing this in IE by chance? Which version? Whilst messing with this I too have come across some very strange behaviour in IE8 regarding outputing certain document.images[n] properties using document.writeln(). The same - only the first iteration of the loop is echo'd. (The examples posted above, however, did work OK for me.) You can alert() the string instead and it appears OK - you just get a lot of alerts! I could only assume this was some king of quirky IE bug!? document.writeln() shouldn't be used in the real world these days anyway (except may be debugging, like above) so it shouldn't be a real problem. I've also found that document.writeln() does not output a newline in IE7 and so behaves the same as document.write().

One last thing - what else can document.images give you? Can it reveal the date the image was uploaded? That would be very useful.


There are actually a lot of properties stored in document.images[n]. However, browsers are very inconsistent in this area and most of which are of very little use to you anyway. For instance, IE8 reports 184 properties, whilst Chrome reports 'only' 57. IE8 does indeed report 'fileCreatedDate', 'fileUpdatedDate' and 'fileModifiedDate', so you can read
document.images[n]['fileCreatedDate'] in IE and it will return a string of the form '07/19/2011' (NB: US Formatted it seems). However, Chrome and Opera return none of these (I've not checked Firefox).

You can get a complete list of all the enumerable properties (which might not be all of them) with this bit of code. This analyses the first image in the document.
var output = ''; 
var img = document.images[0];
for (var imgProp in img) {
output += '<li>' + imgProp + ' (' + typeof img[imgProp] + ') = ';
try {
output += img[imgProp];
} catch(e) {
output += '-ERROR-';
}
output += '</li>';
}
document.write('<ol>' + output + '</ol>');


(Just one document.write() so should be OK! :)

Hester




msg:4341466
 11:04 pm on Jul 19, 2011 (gmt 0)

Thanks! I tested the document write loop in more browsers than IE. They all showed one line only. I will retest some more.

Does "writeln" mean write then make a new line?

I have IE8 not 7 - my mistake!

Will now try your latest code - looks promising!

penders




msg:4341468
 11:22 pm on Jul 19, 2011 (gmt 0)

I tested the document write loop in more browsers than IE. They all showed one line only.


Hhhmm, that's strange, I only had a problem with IE8. All other browsers, including IE7, were OK in this respect. A quick workaround is to move the document.write() outside the loop and append to a string inside the loop (as in the last example to get the image properties).

Does "writeln" mean write then make a new line?


Yes, that's the only difference between write() and writeln() (write line). It writes the newline character "\n".

Note that this is a newline in the source, so depending where you are outputting this you might not actually see the newlines on the page - they might get reduced. Output between <pre>...</pre> tags to preserve the white-space.

Hester




msg:4341478
 11:41 pm on Jul 19, 2011 (gmt 0)

OK, done some more tests. I get just ONE line in ALL browsers. Maybe because of the way the script is inside a function called onload?

Now onto your great images properties script! Not sure where you get the low number for Chrome from. Here's what I get:

Firefox 5 - 135 properties listed
Chrome 12 - 141
Opera 11 - 195
IE8 - 184
Safari 5 - 136

Most are browser-specific information not of much use. Annoyingly ONLY IE gives the file modified etc information, which is what I need! Maybe it is considered a possible security problem in the other browsers?

Of course I could do this in PHP quite easily - hmmm, wonder if I can read the file created date for external images? That could be a way around it!

penders




msg:4341494
 12:08 am on Jul 20, 2011 (gmt 0)

OK, done some more tests. I get just ONE line in ALL browsers. Maybe because of the way the script is inside a function called onload?


This could be it. You could try calling your script at the very bottom of the page before the closing </body> tag.

Not sure where you get the low number for Chrome from.


My mistake, I get 140 in Chrome 10 (my Chrome browser has stopped updating itself; need to fix it). #58 gives an error when it is output which previously broke the script which is why I only saw the first 57 initially and that is what stuck in my head! The try/catch block now traps any errors.

penders




msg:4341733
 3:04 pm on Jul 20, 2011 (gmt 0)

OK, done some more tests. I get just ONE line in ALL browsers. Maybe because of the way the script is inside a function called onload?


The onload event is most definitely the problem with this - at least calling document.write() from within it. Just happened to read this in "JavaScript - The Definitive Guide" by David Flanagan:

Because onload event handlers are invoked after document parsing is complete, they must not call document.write(). Instead of appending to the current document, any such call would instead begin a new document and overwrite the current document before the user even had a chance to view it.


As a general rule of thumb, a document should never call write() on itself from within an event handler.

Hester




msg:4341884
 7:22 pm on Jul 20, 2011 (gmt 0)

I put the code at the bottom of the page and it now works! Only in Firefox everything is on one line.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved