So here’s a fun bug to keep you entertained this weekend. Personally, this is the first purely-JavaScript bug that I’ve seen in IE7 (More due to the lack of anything changing than the quality of the code.)
Summary:
When accessing the .all
or .getElementsByTagName("*")
properties on the DOM representation of an <object> element, the resulting NodeSet will always be empty.
Proof of Concept:
HTML:
<object> <param name="name" value="value"/> <param name="name2" value="value2"/> <param name="name3" value="value3"/> </object>
JavaScript:
var obj = document.getElementsByTagName("object")[0]; // => <object/> obj.all // => [] obj.getElementsByTagName("*") // => [] obj.getElementsByTagName("param") // => [ <param/>, <param/>, <param/> ] obj.firstChild // => <param/>
Andrea has done some fantastic work in tracking this bug down and providing a fix for it.
So far, my quick-and-dirty kludge is just to replace “*” with “param” and hope that the user is actually using an object to hold params, and not some other crazy combination.
Which reminds me – has anyone ever seen an example of an <object> element containing non-param elements on a real, live, web page – somewhere in the wild? The HTML spec says that the <object> element can contain any HTML, but that sounds a little bit too crazy for my tastes.
Sebastian Redl (January 20, 2007 at 8:22 am)
Of course I’ve seen it. Don’t you remember the most popular way of including a Flash movie?
The arbitrary HTML in an object is the fallback content. If the browser, for whatever reason, cannot display the object as it’s supposed to (lacking plugin, cannot retrieve resource, …) it must display the fallback content instead.
Of course, IE doesn’t really support that.
Sebastian Redl (January 20, 2007 at 8:26 am)
OK, so there was supposed to be HTML in that previous comment.
<– For IE –>
<object clsid=”…”>
<– For NS –>
<embed …>
</object>
On a side note, I find your overriding of the text selection style annoying and bad for usability. I cannot tell distinguish whether I’ve selected punctuation or not because the contrast is so low.
John Resig (January 20, 2007 at 12:48 pm)
@Sebastian: I realize that it’s supposed to be the fallback content for an object, but save for embeds in a flash movie, I’ve never seen “fallback” content used.
Regardless, don’t most people use some sort of JavaScript-based Flash-injector these days?
I’m currently working under the assumption that for the vast majority of situations where you want “all elements in side of an object element” that simply looking for “param” would be acceptable. That being said, these are still feasible solutions:
// When you know all the types…
$(“object”).find(“param, embed, p, div, etc.”);
// If you have a wrapper around the object
$(“object .. * *:not(object)”)
I think this is such a fringe case that I’m not terribly concerned, but it’s still important to try and return some results rather than no results. (Of course, completely ignoring the fact that you can just traverse the DOM by hand – as that’s a slow and byte-costly solution.)
I’m not sure what you’re talking about concerning the text selection stuff – I don’t override any of that.
Daniel P (January 22, 2007 at 7:16 am)
What he’s referring to, though he didn’t seem to catch on to the reason for it, is that because the ‘white page’ part of the layout is just an image placed over the blue background.. firefox determines that the background is blue, and makes text selection background white and text foreground darkblue.. Which, on an in actuality white background, makes it very near impossible to see what text you have selected. ;)
Considering the general use of object tags these days is flash content, and it’s as you noted mostly done by javascript to avoid the click-to-activate thing.. I’d say you’re generally pretty in the clear.
It could potentially raise a few issues sometimes if you don’t think about it though, and I have a tendency to forget.
travis (January 22, 2007 at 9:38 am)
This site has HTML in the Object: http://www.careerspace.com/
It is used basically as alt text for users (search engines) without the flash plugin.
The next version of the BrandLogic site (http://www.brandlogic.com/) will work that way also.
We also use object tags instead of an iframe too, since iframes aren’t part of XHTML 1.0 Strict. I don’t think anyone here is trying to select anything inside the object tag though. Since this issue is IE7 only, I wouldn’t worry too much about it.
Sebastian Redl (January 22, 2007 at 4:51 pm)
You’re right of course that the use case will be rare.
But browsing through the source, it seems as if you apply the workaround to all browsers instead of just IE. Am I mistaken?
If not, you might want to limit it to IE. After all, there’s no reason to cripple functionality for other browsers, is there?
travis (January 22, 2007 at 4:59 pm)
yeah i would even just limit it to IE7:
/*@cc_on
@if (@_jscript_version == 5.7)
// IE7 only hack goes here
@end
@*/
John Resig (January 22, 2007 at 5:20 pm)
@Sebastian, travis: I’ve been taking a different stance with cross-browser development, lately. In jQuery, it becomes increasingly hard to maintain a consistent library with all the different cross browser checks. To counteract this, I simply reduce the code down to the largest subset that will work 100% consistently in all browsers. It’s pretty much unacceptable for most users to have to code around browser differences when they’re using a JavaScript Library (which is supposed to be the one responsible for coding around the differences in the first place).
This way, I can easily code my application in Firefox – see an inconsistency (like $(“object *”)), and code around it right there in Firefox. I’m Done. Since I know what my code works in all other browsers, I’ve just cut my development time in 1/Nth (where N is the number of browsers that you test on).
Personally, I find that to be a much better solution (even if it is a crippled one).
Roberto (May 8, 2007 at 10:26 pm)
Hi all,
is anybody aware of any problem with GetElementById( id ).src with IE7 ?
Here is a simple piece of code: a running clock that dynamically changes the gif using getElementById.
http://www.silkypups.com/examples/clock/clock.html
This code works fine with Netscape, IE6… but is stuck with IE7: no running clock.
Any hints ?
curb painting (May 15, 2007 at 1:12 am)
Nice blog!!!!!!!!!!!!good info.
Palak Agrawal (August 9, 2007 at 12:00 am)
Can anybody tell me how to run getelementbyTag in IE7 without help of jquery….
I will appreciate your help