Welcome to Code Couch

Adding document.querySelectorAll support to IE7

Posted by at 9:42am on May 28, 2012.

IE 6 is dead, and I just don’t care about supporting it any more. IE 7 is almost dead, but there are still people using it…, so, if it’s easy to get code working in IE 7 with minimal work required, I don’t see a huge problem with doing so.

I’m currently creating a template which uses the following code to return two label elements:

document.querySelectorAll('label[for="someId1"], label[for="someId2"]')

This code works well in all browsers other than IE 7, because IE 7 doesn’t support document.querySelectorAll.

A quick search showed this 222-byte script on GitHub :

// IE7 support for querySelectorAll in 226 bytes... It's a little slow but better than a 20kb solution when you need something cross platform and lightweight.
(function(d){d=document,a=d.styleSheets[0]||d.createStyleSheet();d.querySelectorAll=function(e){a.addRule(e,'f:b');for(var l=d.all,b=0,c=[],f=l.length;b<f;b++)l[b].currentStyle.f&&c.push(l[b]);a.removeRule(0);return c}})()

Unfortunately, this script didn’t work for me: it kept throwing an “Invalid argument” error.

More searching revealed the MSDN documentation for the addRule method, along with the key detail: Only single selectors are valid; grouped selectors cause “Invalid Argument” error.

The solution to this was easy enough: split the selectors on a “,” and loop round the selectors individually.

Job done? Not yet.

The original code also kept breaking my layout, as it kept removing the first style from the first linked stylesheet on my page. Always using a dynamically created stylesheet fixed that issue.

There was still one issue left to iron out, and it kept me going for a while: the code would run without throwing any errors, but would return no elements when it should have returned two.

I tried simplifying the selector to label[for], yet IE 7 still returned no elements.

Wondering if IE was refusing top work due to “for” being a reserved work in JavaScript (even though we’re dealing with a string here), I tried replacing “for” with “htmlFor” – the method used to access the “for” property from JavaScript – and it worked first time!

From there, it was a simple matter of replacing any “for” attribute selectors with “htmlFor” and it worked perfectly, returning both labels.

Here’s my final code, nicely formatted:

// IE7 support for querySelectorAll. Supports multiple / grouped selectors and the attribute selector with a "for" attribute. http://www.codecouch.com/
(function(d, s) {
	d=document, s=d.createStyleSheet();
	d.querySelectorAll = function(r, c, i, j, a) {
		a=d.all, c=[], r = r.replace(/\[for\b/gi, '[htmlFor').split(',');
		for (i=r.length; i--;) {
			s.addRule(r[i], 'k:v');
			for (j=a.length; j--;) a[j].currentStyle.k && c.push(a[j]);
			s.removeRule(0);
		}
		return c;
	}
})()

And the same code, nice and compact:

// IE7 support for querySelectorAll in 274 bytes. Supports multiple / grouped selectors and the attribute selector with a "for" attribute. http://www.codecouch.com/
(function(d,s){d=document,s=d.createStyleSheet();d.querySelectorAll=function(r,c,i,j,a){a=d.all,c=[],r=r.replace(/\[for\b/gi,'[htmlFor').split(',');for(i=r.length;i--;){s.addRule(r[i],'k:v');for(j=a.length;j--;)a[j].currentStyle.k&&c.push(a[j]);s.removeRule(0)}return c}})()

The only other caveat is listed in the MSDN attribute selector documentation: your page must not be in “quirks” mode. In other words, you must have a valid !DOCTYPE directive.

Post to Twitter

Comments

There are 7 responses to this post.

  1. hot to add this to my code??
  2. @Joseph: Copy & paste
  3. Thanks for the piece of code, was really helpful. Aniway, I had a problem when trying to use it with dynamic content generated with ajax requests. The selector took the generated content even when it didn't match the selector( I think it has more to do with the appendChild instruction than the ajax request itself ). The solution was quite easy, instead of this piece of code: /*a.addRule(e,'f:b');*/ i used this one : /* -a.addRule(e,'f:b', 0); */. It is the first version, but i guess it should work just fine for the extended version too. Hope it helps.
  4. There doesn't seem to be a test to prevent replacing the standard querySelectorAll in a newer browser - what happens in a newer browser?
  5. Hi, I am not able to understand how to use this method in js. I mean how to call it instead of "querySelectorAll" . Please guide me.
  6. @NetMage This post is about IE7... if you want to prevent this code from running in other browsers, you should add your own feature detection around it.
  7. @Ranu: If you run the above code, you should then be able to refer to "document.querySelectorAll".

Leave a reply

You must either log in or enter your name and email address to post a comment.

Your email address will not be published.

  • You do not need to log in to comment, but you can if you wish.
  • Log in