документ 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');
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