Thursday, July 09, 2009

jQuery Firefox error: Could not convert JavaScript argument arg 0 [nsIDOMViewCSS.getComputedStyle]

Update 3rd of March 2016: I've tested for this bug with the latest versions of Internet Explorer, Firefox and Chrome, using the latest jQuery libraries (1.12.1, 2.2.1 and 3.0.0.beta) and it could not be reproduced. The rest of the article may be obsolete.

So I am building this new jQuery based control and I am terribly smug about it until I run the test site on FireFox. Kaboom! Nothing is working. Why? Because FireFox has some issues with the computed style on hidden elements and jQuery people just don't want to fix the problem. But hey, jQuery is open source, right?

So, let's detail the problem. Here is a jQuery bug posting that explains far better than I could what is going on. Apparently, the offsetParent of a hidden element is null in FireFox and the jQuery core function returns the document object when null is given as a parameter [ $(null)==document ]. Then running the FireFox specific function for getting the computed style [ document.defaultView.getComputedStyle(element,null) ] throws an error because the element is now document and it has no style, only its body has.

So, why not fix that? The FireFox error text is '[Exception... "Could not convert JavaScript argument arg 0 [nsIDOMViewCSS.getComputedStyle]" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame :: /jqueryJsFile/ :: anonymous :: line 1349" data: no]'.

The line number might vary with the type of jQuery file version you are using and the amount of modifications you have done to it. What you should find at said line is something like: var computedStyle = defaultView.getComputedStyle(elem, null);.

Solution: Just add above it if (elem == document) elem = document.body; and it solves this particular issue.

In the minifyied version look for var M=q.getComputedStyle(I,null) and add before it if (I==document) I=document.body;

It would be far more elegant to address the problem where the offsetParent is assumed to be not null, but with so many plugins for jQuery, you can't just test them all.


sunil said...

great post! just helped me out a lot. thanks :)

yulii said...

Great! I've taken a lot of trouble with the same issue.
It causes of an error at Opera and Firefox.
Thank you. :)

Bruno said...

Thank you, sir. Just what I needed. Saved me a headache. said...

thanks tons!
What up with the Cats? i kind of love it. I wish this layout were a little friendlier because you have great content. Thanks thanks thanks

Siderite said...

I am glad you like the content. I am not great at web design, so if you have any suggestions, I am willing to listen. You might like the "low band version" of the blog, accessible via the link under the title.

Ariel Popovsky said...

Thanks man! saved me a lot of debugging time.

F. Hobein said...

Just what I needed. Thanks a lot!

Arsen said...

It didn't work for jquery-1.5. Can you test yourself?

I've find the error line 5900

if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
ret = computedStyle.getPropertyValue( name );
if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
ret = elem, name );

and added above it
if (elem == document) elem = document.body;

but it continues to throw an error

Siderite said...

It would be helpful if you could replicate the error in a small piece of code and send it to me. Then I will fix it for you.

Anonymous said...

"var M=q.getComputedStyle(I,null)" isn't present in jquery-1.6.2.min.js, dang..

Siderite said...

All you have to do is debug it and see where the error is generated, then add a bit of code that checks for elem not being document, but document.body.

Anonymous said...

thanks a lot dude!
you save me a lot of hours!

Anonymous said...

Not =>
var computedStyle = defaultView.getComputedStyle(elem, null);

Did you mean =>
var getcomputedStyle = defaultView.getComputedStyle(elem, null);

Siderite said...

No :) I meant what I wrote. But be warned that this post is pretty dated. I don't know how relevant it remains.