документ javascript.совместимость getElementsByClassName с IE



каков наилучший метод для получения массива элементов, которые имеют определенный класс?



Я бы использовал документ.getElementsByClassName, но IE не поддерживает его.



поэтому я попробовал решение Джонатана Снука:



function getElementsByClassName(node, classname) {
var a = [];
var re = new RegExp('(^| )'+classname+'( |$)');
var els = node.getElementsByTagName("*");
for(var i=0,j=els.length; i<j; i++)
if(re.test(els[i].className))a.push(els[i]);
return a;
}
var tabs = document.getElementsByClassName(document.body,'tab');


...но IE все равно говорит:




объект не поддерживает это свойство или метод




любые идеи, лучшие методы, исправления ошибок?



Я бы предпочел не использовать решения, включающие jQuery или другой "громоздкий javascript".



обновление:



я получил его на работу!



как упоминал @joe функция не является методом document.



таким образом, рабочий код будет выглядеть так:



function getElementsByClassName(node, classname) {
var a = [];
var re = new RegExp('(^| )'+classname+'( |$)');
var els = node.getElementsByTagName("*");
for(var i=0,j=els.length; i<j; i++)
if(re.test(els[i].className))a.push(els[i]);
return a;
}
var tabs = getElementsByClassName(document.body,'tab');




...Также если вам нужна только поддержка IE8+ тогда это будет работать:



if(!document.getElementsByClassName) {
document.getElementsByClassName = function(className) {
return this.querySelectorAll("." + className);
};
Element.prototype.getElementsByClassName = document.getElementsByClassName;
}


используйте его так же, как обычно:



var tabs = document.getElementsByClassName('tab');
678   7  

7 ответов:

Это не метод документа:

function getElementsByClassName(node, classname) {
    var a = [];
    var re = new RegExp('(^| )'+classname+'( |$)');
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
}

tabs = getElementsByClassName(document.body,'tab');  // no document

вы можете создать функцию для старых браузеров

if (typeof document.getElementsByClassName!='function') {
    document.getElementsByClassName = function() {
        var elms = document.getElementsByTagName('*');
        var ei = new Array();
        for (i=0;i<elms.length;i++) {
            if (elms[i].getAttribute('class')) {
                ecl = elms[i].getAttribute('class').split(' ');
                for (j=0;j<ecl.length;j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            } else if (elms[i].className) {
                ecl = elms[i].className.split(' ');
                for (j=0;j<ecl.length;j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            }
        }
        return ei;
    }
}
function getElementsByClassName(className) {
if (document.getElementsByClassName) { 
  return document.getElementsByClassName(className); }
else { return document.querySelectorAll('.' + className); } }

уверен, что это то же самое, что и функция Леонида, но это использует document.getElementsByClassName, когда он может.

вы не можете действительно реплицировать getElementsByClassName, потому что он возвращает список узлов, и так его значение живое, и обновления с документом.

вы можете вернуть статический массив элементов, которые имеют одинаковые имена классов- но он не будет "знать", когда документ изменится.

(Это не займет слишком много подобных вещей, чтобы сделать библиотеку выглядеть стройной...)

function getArrayByClassNames(classes, pa){
    if(!pa) pa= document;
    var C= [], G;
    if(pa.getElementsByClassName){
        G= pa.getElementsByClassName(classes);
        for(var i= 0, L= G.length; i<L; i++){
            C[i]= G[i];
        }
    }
    else{
        classes= classes.split(/\s+/);
        var who, cL= classes.length,
        cn, G= pa.getElementsByTagName('*'), L= G.length;
        for(var i= 0; i<cL; i++){
            classes[i]= RegExp('\b'+classes[i]+'\b');
        }
        classnameLoop:
        while(L){
            who= G[--L];
            cn= who.className;
            if(cn){
                for(var i= 0; i<cL; i++){
                    if(classes[i].test(cn)== false) {
                        continue classnameLoop;
                    }
                }
                C.push(who);
            }
        }
    }
    return C;
}

//пример

var A= getArrayByClassNames ('sideBar местные')

IE8:

document.getElementsByClassName = function (className) {
    return document.querySelectorAll('.' + className)
}
function _getClass(whatEverClasNameYouWant){
var a=document.getElementsByTagName('*');
   for(b in a){
      if((' '+a[b].className+' ').indexOf(' '+whatEverClasNameYouWant+' ')>-1){
      return a[b];
      }
   }
}

Я просто хочу улучшить querySelectorAll запасной вариант для IE8.

как и другие ответили, простой способ-добавить функцию в Element.prototype С

this.querySelectorAll('.' + className);

но есть несколько проблем:

  • он не работает с необрезанными строками (в начале).
  • он не работает с несколькими классами.
  • он не работает со "странными" персонажами класса (/,$,* и т. д.)
  • он не работает с классы, которые начинаются с цифры (недопустимые идентификаторы)

это означает, что должно быть какое-то" исправление", например:

"abcd"     ->  ".abcd"
"a   b cd" ->  ".a.b.cd"
"   a b  " ->  ".a.b  "
"a/b$c d"  ->  ".a\/b$c.d"
"1234"     ->  ".0031234"

код:

this.querySelectorAll(className
    .replace(/(?=[^ \w])/g, '\')   // Escape non-word characters
    .replace(/\b\d/g, '\00003$&')  // Escape digits at the beginning
    .replace(/(^| +)(?!$| )/g, '.') // Add "." before classes, removing spaces
);

Comments

    Ничего не найдено.