Adding document.querySelectorAll support to IE7

2013/05/11 21:13
阅读数 411

Adding document.querySelectorAll support to IE7

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. (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. (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.

0 收藏
0 评论
0 收藏