2013-05-10 2 views
4

С кодом от this article Я успешно добавил querySelectorAll в document в IE7.Как добавить функцию querySelectorAll() в элемент для IE <= 7?

Но мне нужно, чтобы использовать его на элемент, а не 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, а не только document?

+0

Почему бы не попробовать [библиотеку Sizzle] (https://github.com/ JQuery/шипение/вики/шипение-документация). Это тот же механизм выбора, который использует jQuery. – Joseph

+0

Мне нужно, чтобы код был крошечным, не нужно ненужных функций. ;-) –

+0

Sizzle - всего 4 КБ. – Joseph

ответ

7

Очень интересный вопрос.

Я бы наклонился к использованию библиотеки для этого, например jQuery, один из перечисленных ниже, Closure, или any of several others. Или просто используя Sizzle (механизм селектора jQuery используется в ветке v1.9).

Но отвечая на вопрос, который вы на самом деле спросили:

Вы не можете расширить прототипы элементов на IE7 (к сожалению), так что если вы не хотите, чтобы запустить все экземпляры элементов с помощью функции препроцессора добавить querySelectorAll к ним (например, Prototype и MooTools), вам придется иметь отдельную функцию, в которую вы передаете элемент.

Вот один подход к написанию этой функции:

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 
    // ... 
} 

Но опять же, я бы склоняюсь к использованию библиотеки ...