перебрать все доступные узлы getElementsByClassName

Для моего проекта мне нужно получить коллекцию всех элементов одного класса. Итак, я делаю это с getElementsByClassName.

var tabs = document.getElementsByClassName("tab");

if (tabs) {
    for (var i = 0; i < tabs.length; i++) {
        var tab = tabs[i];
        console.log(tab);    // which outputs as 'undefined'..
        console.log(i);    // which outputs the nos of the total nodes available with class 'tab'
    }
}

Я должен получить все эти элементы (у которых есть класс «вкладка») и применить его к другому классу (скажем, «летучая мышь»).

Мой вопрос в том, почему он утешает undefined, как указано выше?? и как я могу последовательно перебирать все необходимые узлы. Есть ли какой-нибудь код, который может это сделать??

ИЗМЕНИТЬ ::

Забудь добавить..

При нажатии на любую вкладку с классом 'tabs' она всегда возвращает один и тот же результат.

var tabs = document.getElementsByClassName("tab");

if (tabs) {
    for (var i = 0; i < tabs.length; i++) {
        var tab = tabs[i];
        tab.addEventListener("click", function() {
            console.log(tab[i]);  // always returns undefined
            console.log(tab);  // always returns the last element in the list
            console.log(i);  // always returns the length of that list (in my case its 3)
        }, false);
    }
}

Как я могу последовательно перебирать все доступные элементы.


person bantya    schedule 29.12.2015    source источник
comment
Что выводит console.log(tabs)?   -  person roland    schedule 29.12.2015
comment
console.log(tabs) предоставляет список всех доступных элементов с именем класса 'tab'..   -  person bantya    schedule 29.12.2015
comment
Работает, как и ожидалось здесь — регистрирует каждую вкладку, за которой следуют 0, 1 и 2. Можете ли вы показать нерабочий пример?   -  person Paul Roub    schedule 29.12.2015
comment
Это фактический код выше?   -  person epascarello    schedule 29.12.2015
comment
epascarello, отредактированный код - мой фактический код..   -  person bantya    schedule 29.12.2015
comment
tab[i] определенно опечатка вместо tabs[i]. Кроме того, взгляните на добавление прослушивателей событий click в цикле для узнайте о замыканиях и о том, как они доставляют вам проблемы.   -  person Paul Roub    schedule 30.12.2015


Ответы (3)


Вы можете превратить NodeLiist в массив. Кстати, ваш tab[i] должен быть tabs[i], я думаю.

var tabs = document.getElementsByClassName('tab');
var tabArray = Array.prototype.slice.call(tabs);
for(var i = 0; i < tabArray.length; i++) {
     console.log(tabArray[i].id);
     console.log(i);
     tabArray[i].innerHTML = "t"+(i+1);
     
};
<div id="t1" class="tab">t</div>
<div id="t2" class="tab">t</div>
<div id="t3" class="tab">t</div>
<div id="t4" class="tab">t</div>
<div id="t5" class="tab">t</div>
<div id="t6" class="tab">t</div>
<div id="t7" class="tab">t</div>
<div id="t8" class="tab">t</div>

person zer00ne    schedule 29.12.2015

Будьте осторожны с getElementsByClassName(), как указано в документах Mozilla возврат представляет собой массивоподобный объект, а не массив. Еще один момент заключается в том, что return является живой HTMLCollection, поэтому, если вы хотите изменить имя класса в цикле, коллекция будет обновляться в реальном времени на лету и вызывать неожиданное поведение. Я сделал пример с регистром изменения класса. Проверьте полный код по ссылке ниже.

http://codepen.io/renatocolaco/pen/VemMNy

function btnClick(event){

event.preventDefault();

//action goes here
var boxes = document.getElementsByClassName("box");

console.log("fouded elements: " + boxes.length);
var element = boxes.item(0);
while(element){
    element.className = "another_box";
    element = boxes.item(0);
}

//doesn't work
//var cache = boxes.length;
//for(var i = cache; i < boxes.length; i++){
//    console.log(boxes[0]);
//    boxes[0].className = "another_box";
// }

//doesn't work
//Array.prototype.forEach.call(boxes, function(element, index, array){

    //array[index].className = "another_box";

//});
}

Обновление: вторая проблема, когда вы добавляете событие на вкладки, у вас возникает проблема с закрытием. Это связано с тем, что в момент вызова метода onclick (для любой из вкладок) цикл for уже завершен, и переменная i уже имеет значение (размер вашей коллекции).

Оберните свой код внутри самовыполняющейся функции следующим образом:

(function (i) {
  tab.addEventListener('click', function() { console.log(i); });
})(i);
person Renato Colaço    schedule 29.12.2015

Вы использовали JQUERY раньше? Это может быть более легкий путь. Таким образом, вы можете использовать $(".tab"). Вы также можете использовать .forEach() вместо цикла for? Может сделать это более простым

Кроме того, пример Пола, кажется, работает, можете ли вы предоставить неработающий JSfiddle?

person Scott Stern    schedule 29.12.2015
comment
Нет, я раньше не использовал jquery. Теперь пробую ваше предложение forEach().. - person bantya; 29.12.2015