6

使用本文中的代码,我已成功添加querySelectorAlldocumentIE7 中。

但我需要在一个元素上使用它而不是document,像这样:

var containers = document.querySelectorAll('.container');   // Works
for (var i=0; i<=containers.length; i++) {
    var container = containers[i];
    container.querySelectorAll('a[data-type="people"]');    // Fails
    // ...
}

有没有办法添加querySelectorAll到 IE7 中的元素而不仅仅是添加到 IE7 中document

4

1 回答 1

9

非常有趣的问题。

我倾向于为此使用库,例如​​ jQuery,下面提到的其中之一,Closure其他几个中的任何一个。或者只是使用Sizzle(jQuery 在 v1.9 分支中使用的选择器引擎)。

但回答你实际提出的问题:

你不能在 IE7 上扩展元素原型(很遗憾),所以除非你想通过预处理器函数运行所有元素实例以添加querySelectorAll到它们(例如PrototypeMooTools的工作方式),否则你必须拥有您将元素传递到的单独函数。

这是编写该函数的一种方法:

var qsaWorker = (function() {
    var idAllocator = 10000;

    function qsaWorker(element, selector) {
        var needsID = element.id === "";
        if (needsID) {
            ++idAllocator;
            element.id = "__qsa" + idAllocator;
        }
        try {
            return document.querySelectorAll("#" + element.id + " " + selector);
        }
        finally {
            if (needsID) {
                element.id = "";
            }
        }
    }

    return qsaWorker;
})();

当然,如果你想qsaWorker在有 的浏览器中使用querySelectorAll,你会想要这个:

function qsaWorker(element, selector) {
    return element.querySelectorAll(selector);
}

所以总的来说,你可能想要:

var qsaWorker = (function() {
    var idAllocator = 10000;

    function qsaWorkerShim(element, selector) {
        var needsID = element.id === "";
        if (needsID) {
            ++idAllocator;
            element.id = "__qsa" + idAllocator;
        }
        try {
            return document.querySelectorAll("#" + element.id + " " + selector);
        }
        finally {
            if (needsID) {
                element.id = "";
            }
        }
    }

    function qsaWorkerWrap(element, selector) {
        return element.querySelectorAll(selector);
    }

    // Return the one this browser wants to use
    return document.createElement('div').querySelectorAll ? qsaWorkerWrap : qsaWorkerShim;
})();

您使用它的代码将如下所示:

var containers = document.querySelectorAll('.container');
for (var i=0; i<=containers.length; i++) {
    var container = containers[i];
    var links = qsaWorker(container, 'a[data-type="people"]'); // <== Changed
    // ...
}

但同样,我倾向于使用图书馆......

于 2013-05-10T08:52:10.323 回答