2013-12-02 4 views
0

После нескольких попыток жесткого кодирования рекурсивного метода getElementsByClassName, я остановился со следующим:Запрограммированное getElementsByClassName Рекурсивного (element.className против element.classList.contains)

var getElementsByClassName = function(className) { 
    var result = []; 

    function inspect(element) { 
    var children = element.children; 
    for(var i = 0; i < children.length; i++) { 
     if(children[i].classList.contains(className)) { 
     result.push(children[i]); 
     } 
     if(children[i].hasChildNodes) { 
     inspect(children[i]); 
     } 
    } 
    } 

    inspect(document); 
    return result; 
}; 

Однако я не могу понять, почему это решение не работает, учитывая имя класса возвращает значение, которое мы можем испытать против:

var getElementsByClassName = function(className) { 
    var result = []; 

    function inspect(element) { 
    if (element.className === className) result.push(element); 

    var children = element.children; 
    for(var i = 0; i < children.length; i++) { 
     inspect(children[i]); 
    } 
    } 

    inspect(document); 
    return result; 
}; 

Спасибо за помощь, заранее, и если у вас есть какие-либо другие предложения по улучшению моего кода, пожалуйста, дайте мне знать.

+0

Что не работает? Что происходит вместо этого? Это как раз о 'classname' vs' classlist', или вы спрашиваете о разных структурах кода? – Bergi

+0

FYI, '.hasChildNodes' не вызывается в инструкции' if'. Вместо этого вы оцениваете сама функция, которая всегда будет «истина», если она определена. –

+1

Ваше второе решение отлично подходит для меня. Вероятно, было бы неплохо проверить, что «дети» действительно существуют. И, конечно, сравнение 'className' не будет выполнено, если есть несколько классов. –

ответ

1
  1. ваш, если необходимо обновить, потому что есть некоторые случаи, в которых элемент может иметь более одного класса к нему заявление. В настоящее время вы просто проверяете, есть ли только один класс. Вы можете либо использовать метод contains, чтобы проверить его с помощью indexOf, как я сделал ниже, чтобы узнать, включено ли в список требуемое имя класса.
  2. При вызове вашего рекурсивного вызова вы используете документ. Я не слишком уверен, но я верю, что вы хотите вызвать document.body ... Это означает, что вы пытаетесь назначить var children для document.children при первом вызове функции, однако вы хотите вызвать документ . body.children, а также для оператора if document.body.classname ... поэтому при вызове рекурсивного вызова оно должно быть проверить (document.body). Если вы хотите использовать документ, тогда вам придется используйте document.childNodes .... однако лучше использовать document.body.children, потому что document.childNodes добавляет пробелы в результат между каждым элементом. Так что если есть 3 ребенка, то document.body.children будет иметь длину 3, но document.childNodes будет иметь длину 5. Вы можете сделать эту же функцию, используя дочерние элементы вместо childen, однако вы используете метод contains внутри блока if было бы лучше использовать в этом случае.

heres решение для u, которое использует ваш алгоритм, но есть более эффективные способы реализации, и вы также можете сделать это без внутренней функции.

var getElementsByClassName = function(className) { 
    var result = []; 

    function inspect(element, result) { 
    var children = element.children; 
    var parts = element.className.split(' '); 
    if(parts.indexOf(className) >= 0){ 
     result.push(element); 
    } 
    for(var i = 0; i < children.length; i++) { 
     inspect(children[i], result); 
    } 
    } 

    inspect(document.body, result); 
    return result; 
}; 
Смежные вопросы