Sometimes, even jQuery can’t save you from yourself
General, jQuery By Dave Ward. Posted July 8, 2010I recently encountered what appeared to be a cross-browser issue with jQuery, which was both surprising and frustrating. After all, eliminating those cross-browser inconsistencies is no small part of jQuery’s fundamental appeal.
After some investigation, the source of the trouble actually stemmed from an oversight on my part. I doubt that many of you will have to deal with exactly the same situation, but the lessons I learned may apply to cross-browser jQuery problems you encounter in the future.
Tables all the way down
It all started with a relatively simple HTML table template being rendered on the client-side via jTemplates. The rendered markup looked something like this:
<table> <thead> <th>Part Number</th> <th>Description</th> <th>Quantity</th> </thead> <tbody> <tr> <td>Item1</td> <td>Item1 Description</td> <td>4</td> </tr> <tr> <td>Item2</td> <td>Item2 Description</td> <td>2</td> </tr> </tbody> </table>
A series of these tables would be rendered in chronological order, one per invoice.
The bit of jQuery in question
Once those tables were rendered, the user often needed to trigger an action on the first row of the last table. The action itself isn’t relevant, but one important detail is that it blocked interaction with the rest of the page until its workflow was complete.
Glancing at the markup, the selector to accomplish that seemed simple enough:
$('table:last tr:first').triggerSomeAction();
Nice, simple, and it worked great. We tested it thoroughly, got user-approval, and I moved on to other features.
Unfortunately, that single line of jQuery would come back to haunt me later.
IE failed me? It’s always IE!
Originally, I was fortunate enough that all this application’s users were using recent versions of Firefox. Since all my development took place in Firefox too (you still can’t beat Firebug), the application received very little cross-browser testing.
Over time, the application became a victim of its own success. It worked so well that other departments began to adopt it too; departments with Internet Explorer users. All of the IE users were using IE8, so that wasn’t as bad as it could have been, but it brought an interesting cross-browser problem to my attention.
The problem was that the bit of code which called triggerSomeAction() on the first row of the last table wasn’t working right in IE. Worse yet, it was still locking the interface though. IE users were unable to complete that bit of the workflow and remained locked out of the invoices once that action had been triggered.
I cursed IE, out of habit, and went to work debugging the issue.
Nope, I had failed myself
Tracing through the code, it seemed like the selector was finding the <thead> row instead of the first row of the table body. That didn’t make much sense at first, but then I inspected the rendered markup side-by-side in both Firebug and IE’s developer tools:

See the difference?
Firefox had been rendering the table’s markup exactly as given, even though omitting a <thead>’s <tr> isn’t valid markup, but IE tried to fix my mistake by inserting the missing <tr>. In fact, this behavior isn’t unique to IE. Chrome and Safari both do the same thing that IE does with that particular malformation.
Because jQuery’s selectors act on the DOM itself, not the raw HTML that was originally fed to the browser, this “help” was changing the result of my jQuery selector. Selecting tr:first was actually returning the row of <th> elements in every browser other than Firefox.
I stopped cursing IE and began cursing myself.
The fix
The fix was simple enough. I changed the selector to be more precise:
$('table:last tbody tr:first').triggerSomeAction();
That fixed the immediate problem. Then, I corrected the template’s missing <tr> for good measure.
What I learned
Validating HTML has a reputation as something only obsessive purists do, but Validating you HTML is a useful tool. It’s lint for your HTML. I’m often lax about validating internal-only sites, but doing that would have helped me avoid this problem before it happened.
If a jQuery selector seems inconsistent across browsers, inspect the DOM in those browsers. It’s not safe to assume that every browser will interpret your markup as its written. Thankfully, most browsers now include tools suitable for doing so.
If you think you’ve “found a problem” with a mature library like jQuery, blame yourself first. I should have known better than to think there was a problem with jQuery in such a common scenario.
And you?
I hope that having watching my mistake unfold in slow-motion will help you if you run into a similar issue in the future. Even better, maybe it will help you avoid the problem in the first place!
Do you have a similar story? What are the cross-browser issues you’ve run into when using jQuery?
Similar posts
What do you think?
I appreciate all of your comments, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums or Stack Overflow instead.
If you're replying to another comment, use the threading feature by clicking "Reply to this comment" before submitting your own.
2 Mentions Elsewhere
- Tweets that mention Sometimes, even jQuery can’t save you from yourself | Encosia -- Topsy.com
- The Morning Brew - Chris Alcock » The Morning Brew #639



I had a similar issue when jQuery did nothing. After lots of investigation with FireBug…etc, cursing jQuery, the issue was my own. The jQuery was correct, the DOM element wasn’t loaded when I was trying to reference it. When all else fails, use document.getElementById to get the truth!
Do the W3C validators work on Javascript generated HTML or do you have some other tools for that?
The Firefox Web Developer addon has an option in the tools menu called “Validate Local HTML” that sends your generated HTML to the W3C validator instead of just validating by URI. Just keep in mind that it’s sent to the validator in cleartext and be sure not to validate anything sensitive that way.
Dave,
Lesson learnt.
Yeah, I ran into a similar issue. With tables too. I called .hide() for a detached element just created with $(…html code from a server…) call. It was TR. Then this TR was added to a table and some time after that it had to be shown with .show() call. But it didn’t want to show correctly in Firefox. And this time a problem was with jQuery. Its implementation of hide()/show() saves an initial value of the property display into element’s data and then uses it to show the element. But this value for a detached TR in Firefox is ‘block’, not ‘table-row’. My dumb fix looked like this:
Dave, I’ve made exactly the same mistake before, those pesky tables!
We had something similar: an unclosed IMG tag actually killed IE6 stone dead!
Took us ages to find the issue.
never question the jquery!
thanks for this much needed reminder that sometimes the problem is right in front of your face, and almost always, that problem was your fault!
I too have been bitten by IE’s propensity to ‘help’ (And currently by a thousand midegs – but we won’t go into that one!)
The whole history of browser compatibility and ‘broken’ websites has not really been made any easier by the fact that browsers silently (or other wise) correct our mistakes. If they had never sone this in the first plac, then developers everywhere (myself included) would have been forced to produce correct markup, and there would be one less problem to think about.
Having your webpage fail immediately may seem to be a bit draconian, but the failure would be immediate and visible, not delayed and ‘lurking’.
Oh well, in a perfect world…
Be careful using Firebug’s HTML for low-level tracing like this — it will sometimes correct a “problem” — the actual view source is required.
I was missing a closing tag and FireBug closed it for me. That missing closing tag was causing all sorts of grief in IE. Took several hours before I checked raw source.
As always, enjoy reading your articles.
That’s a good reason TO use firebug’s HTML (DOM) view – compare it with the output from ‘View Source’ and you might spot some of the ‘help’ that the browser is giving you. By saving the output from both views, to separate text files, and using a decent Diff tool (Beyond Compare, for example), any differences shoudl be obvious.
The same theory applies to IE ‘View Source’ and DeveloperTools DOM view.
On a related note, I know that some versions of IE will treat an invalid self-closing tag as if it were a start tag without an end tag, whereas firefox (and others) seems to be inclined to close it for you. This can be hard to track down at times.
Good thing to point out…
However, you really shouldn’t be using that markup in the first place. A cell without a row just makes no sense, and it’s very much invalid.
I think a bigger lesson to learn here is to always write the most valid markup you can.
Thanks Dave. I don’t work with web applications too much any longer, but still found this as an interesting read. Your point about validating HTML is well taken, and hopefully I’ll remember it as I get back into web development again in the future.
-Mark