1

I'm trying to make my current project IE7-compatible. We are not using jQuery, but instead using querySelectorAll for our selector needs. However, IE7 doesn't support querySelectorAll, so I've monkey-patched it with code from https://gist.github.com/868532. It actually works fine, except for one small difference: instead of a NodeList like the original querySelectorAll, it returns an array. Since I'd like to stay as compatible as possible, I wanted to make that function return a NodeList. Using some method found on the net, I've adapted the gist to this:

(function(d) {
     d=document, a = d.styleSheets[0] || d.createStyleSheet();

     if (! vxJS.isHostMethod(d, 'querySelectorAll')) {
         d.querySelectorAll = function(e) {
             a.addRule(e,'f:b');

             for (var l=d.all, b=0, c=d.createDocumentFragment(),f=l.length; b<f; b++) {
                  l[b] && l[b].currentStyle.f && c.appendChild(l[b].cloneNode(true));
             }
             a.removeRule(a.rules.length - 1);
             return c.childNodes;
         };
     }
 })();

My problem with this code is that appendChild removes a node from its original location in DOM tree, therefore I tried creating a clone with cloneNode, which obviously creates valid node clones, which are not the original nodes and thus cannot be used in further code.

Is there any way I can put a real node reference into a NodeList?

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Nikolai Prokoschenko
  • 8,465
  • 11
  • 58
  • 97
  • @rassie Is there a specific reason why you want to produce a NodeList instance instead of an Array instance? It appears that the only additional feature of a NodeList instance is the `item()` method which is not needed in practice, because you can use `[i]` instead of `.item(i)` to grab the `i`-th element. – Šime Vidas Apr 15 '11 at 15:08
  • @Šime Vidas: Let's say it's my natural curiosity :) The main reason has been the compatibility with original QSA, which as you say is basically being able to `.item()` something, so actually your comment helps a lot to solve a particular coding problem, since I didn't know it can be accessed over array indexes (put it into an answer for credit ;-)). However, as a bonus, it'd still be nice to know whether and how those NodeLists can be created manually, but that's probably a whole different issue. – Nikolai Prokoschenko Apr 15 '11 at 16:33
  • @rassie In JavaScript, a given property of a given object `obj` can be accessed by `property_name` like so: `obj[property_name]`. And since the property names of NodeList instances are indexes (0, 1, 2, ...), the `[i]` notation works as expected. I would also like to know how to produce NodeList instances, so I'm going to wait for an answer. I might also put a bounty on this one if no answer is posted by tomorrow ... – Šime Vidas Apr 15 '11 at 18:46
  • @rassie *"Using some method found on the net, I've adapted the gist to this"* - could you provide a link to this resource? I would like to know about that method. It appears to be about populating a document fragment. – Šime Vidas Apr 15 '11 at 21:29
  • @Šime Vidas: That's no big "resource", rather a fellow answer here on SO: http://stackoverflow.com/questions/1776769/creating-a-dom-nodelist. I've taken the gist above and replaced the array filling functionality with a NodeList, only to notice later that I cannot `appendChild` a node without removing it from its original place in DOM tree. – Nikolai Prokoschenko Apr 15 '11 at 21:43
  • @rassie Aha, I see. This technique exploits the fact that the `childNodes` property returns a NodeList instance. – Šime Vidas Apr 15 '11 at 21:49

2 Answers2

0

I don't think that it can be done.

The NodeList instances which IE7 is able to produce are live NodeLists. However, the querySelectorAll method is defined to return a static NodeList instance. I don't believe that IE7 knows what a static NodeList is - those were (afaik) only introduced in the Selectors API.

Read about live NodeLists and static NodeLists here.

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • I'm afraid you are right here. Even though NodeList and HTMLCollection objects are available, there is no accessible constructor for them, i.e. only a native implementation. Let's wait a bit for some other pointer (even though I doubt there will be one, I've done my research too) before I accept the answer. – Nikolai Prokoschenko Apr 15 '11 at 21:47
  • @rassie You don't have to accept it, I am merely assuming. It would make more sense to leave this question open. – Šime Vidas Apr 15 '11 at 21:59
0

Perhaps you can make your Array mimicking NodeList by adding the item() method.

if (!Array.prototype.item) {
    Array.prototype.item = function (i) {
        "use strict";

        return this[i];
    };
}
Cabu
  • 51
  • 1
  • 2