let tabsBtn = document.querySelectorAll('.services__tabs-item');
let tabsContent = document.querySelectorAll('.services__item');
for (let i = 0; i < tabsBtn.length; i++) {
tabsBtn[i].addEventListener('click', function(evt) {
evt.preventDefault();
for (let j = 0; j < tabsContent.length; j++) {
tabsBtn[j].classList.remove('services__item--active');
tabsContent[j].classList.remove('services__tabs-item--active');
}
let index = tabsBtn.indexOf(this);
this.classList.add('services__tabs-item--active');
tabsContent[index].classList.add('services__item--active');
});
}
По идее, если я все правильно понял, то такой код должен работать.
Суть в том, что иттератор передавать в прослушку события бессмысленно, цикл пройдет и закончится, значение иттератора будет больше длины массива, и это произойдет за доли секунды, а когда пользователь кликнет по табу вызовется функция с иттератором, который будет во-первых всегда статичным, а во-вторых - больше длины массива (иначе, цикл бы продолжался), поэтому Ваш код всегда будет давать андефайнд. Вместо иттератора лучше использовать this, когда человек кликнет на кнопку в this попадет текущая кнопка, по которой кликнули, и мы сначала удаляем активный класс у всех кнопок и контента, а потом текущей кнопке его назначаем. Второе, как я понимаю, что индекс кнопки и индекс таба должен совпадать, иначе код надо будет усложнить. Если индексы совпадают, то создаем локальную переменную, которая вернет индекс кнопки, по которой кликнули, просто находим индекс массива кнопок по объекту this, то есть по кнопке, на которой произошло событие, далее берем этот индекс и находим элемент по этому индексу из массива контента, и ему назначаем активный класс. В результате меньше функций.
Если индексы НЕ совпадают, тогда можно пройтись по всем табам и кнопкам и задать им дата атрибуты, а потом при клике вытаскивать по дата атрибутам нужные элементы и назначать классы, а вот удалять классы, думаю оптимально перед тем, как задать, и удалять классы у всех, а потом активным их задавать.