Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   getElementsByClassName (https://javascript.ru/forum/events/16086-getelementsbyclassname.html)

dima_zluka 25.03.2011 14:40

getElementsByClassName
 
Это мой вариант функции getElementsByClassName. Я в нём я попытался учесть все варианты.
function byClass(elem,classList){
    if(typeof elem=='string'){
        classList=elem;
        elem=document;
    }
    var retElems=[];
    if(elem.getElementsByClassName)//Проверяем поддержку getElementsByClassName
        retElems=elem.getElementsByClassName(classList);
    else if(elem.querySelectorAll)//Разбиваем строка на массив и тут же склеиваем с вставкой ' .'
        retElems=elem.querySelectorAll('.'+classList.split(' ').join('.'));
    else{//Если нет то ищем вручную 
        classList=classList.split(' ');//Разбираем на масcив 'class1 class2'.split(' ')=['class1','class2']
        var classElemList=[];
        var elemList=elem.getElementsByTagName('*');//Получаем всех потомков elem
        var trueList=[];
        var elemLen=elemList.length;
        for(var a=0;a<elemLen;a++){//Перебор всех элементов
            classElemList=elemList[a].className.split(' ');//Разбираем на массив классы текущего
            if(classElemList.length>=classList.length){//Если количество классов больше то продолжаем
                trueList=[];
                //Дальше идёт проверка есть ли эти классы  в элементе
                for(var b=0;b<classElemList.length;b++)
                    for(var c=0;c<classList.length;c++)
                        if(classElemList[b]==classList[c]) trueList.push(true);
                //Если количество совпавших равно то добавляем
                if(classList.length==trueList.length)retElems.push(elemList[a]);
                //Больше нельзя будут не совпадения с getElementsByClassName
            }
        }
    }
    return retElems;
}

Переделал, добавил querySelectorAll и немного увеличил скорость.
Пример использования
byClass(document.getElementById('div1'),'nav class1')[2].style.color='#0ff';

или
byClass('class2')[0].style.color='#f00'
Хочу узнать про недоработки.
Заранее спасибо.

Matre 25.03.2011 15:05

В IE8 есть querySelectorAll, но нет getElementsByClassName, необходимо делать проверку на наличие.

goldserg 25.03.2011 17:04

Старайся избегать
for(var a=0;a<elemList.length;a++)
Такая конструкция жрет оооочень много особенно для HTMLCollection в котором до хрена элементов.
var len = elemList.length
for(var a=0;a<len;a++)

Sweet 25.03.2011 17:43

Было бы неплохо сделать так, что если elem - строка, то
classList = elem;
elem = document;
А еще посмотри здесь: пример удачной реализации

dima_zluka 25.03.2011 18:34

Спасибо добавил.

FINoM 08.04.2011 05:05

dima_zluka, учти, что пользователь может всунуть в атрибут классы, чередующиеся с несколькими пробелами. То есть:
' valera   volodia '.split(' '); // вернет ["", "", "", "valera", "", "", "", "", "", "volodia", ""]

' valera   volodia '.split(' ').join('.'); // вернет "...valera......volodia."

goldserg 13.04.2011 11:45

split(/\s+/)


Часовой пояс GMT +3, время: 20:21.