Как передать элементы массива в html с помощью JS

Есть массив с данными https://jsfiddle.net/LenaR/enw0Lc3t/
которые должны заполнить div-блоки с помощью цикла при клике по блоку).
Почему ошибка undefined и только в первом блоке? (в первый селектор все элементы массива передаются? Тогда блокам дать разные Id? Но как тогда передать в разные Id?) И почему блок при клике смещается вниз?

(P.S. Если что-то похожее проходили на курсе 2014 подскажите ссылку где посмотреть)

У меня так получилось:

var firstArr = ["1", "2", "3", "4", "5", "6", "7", "8"];

	var fillBlock = (function() {
		var el = document.querySelectorAll('.block');
				for(i=0; i<=firstArr.length-1; i++) {
			el[i].innerHTML = firstArr[i];
			console.log(firstArr[i]);
		}
	});
	
var oncl = document.querySelector('.block');
oncl.addEventListener('click', fillBlock, false);

Вы делаете поиск первого селектора и все. А надо выбрать все элементы и потом циклом пройтись по ним document.querySelectorAll. Плюс вы пропустили в массиве цифру 6. Так же надо иметь ввиду, что oncl.addEventListener(‘click’, fillBlock, false); не отрабатывает на все элементы если пытаться повесить слушатель на document.querySelectorAll.

2 лайка

то есть, там также надо повесить слушатель на querySelectorAll?

var oncl = document.querySelectorAll('.block');

чтобы скрипт срабатывал для клика по любому из блоков, а не только по первому. Вы это имеете ввиду? Если да, тогда скрипт в консоли выдает ошибку oncl.addEventListener is not a function

(Это не обязательное условие, чтобы можно было кликать по любому блоку).

то есть, там также надо повесить слушатель на querySelectorAll?

qerySelectorAll возвращает массивоподобный объект. В возвращаемом объекте нет метода addEvenListener (этот метод есть только у DOM узлов). Тебе нужно пробежаться по каждому элементу массивоподобного объекта и на каждом объетке вызвать addEventListener.

TLDR;
Открывайте отладчик, ставьте break points в неочевидных местах и смотрите что происходит.

Полный ответ

  1. Есть массив с данными […]
var firstArr = ["1", "2", "3", "4", "5", "7", "8"];

Как уже было отмечено выше, Вы упустили цифру “6”. Таким образом длинна массива с данными стала равна не 8, как ожидалось, а 7. Это bug т.к. в дальнейшем в цикле Вы полагаетесь на то, что иттераций должно быть именно 8 ( for(i=0; i<=8; i++) {...} ).

  1. […] которые должны заполнить div-блоки с помощью цикла при клике по блоку.

По какому блоку? Первому, последнему или n-ому? Ваша реализация сейчас работает при клике по первому блоку, но это совсем не очевидно. Best practice было бы задать некий идентификатор, который должен был бы отвечать за js-функционал. Например, id.

При таком подходе поиск элемента для того, чтобы повесить обработчик становится легче. Можно воспользоваться:

  1. document.getElementById('fill-block') // обратите внимание, что не нужно писать # в селекторе
  2. document.querySelector('#fill-block')

Оба эти варианта вернут нам один элемент.

3.1 Почему ошибка undefined и только в первом блоке?

Смотрим на функцию-обработчик и видим:

var filling = document.querySelector('.block');

Проблема в том, что document.querySelector возвращает первый найденный элемент. То есть фактически это первый <div> из верстки. И .т.к. Вы поместили его в переменную filling, то и все дальнейшие действия в цикле происходят именно с ним одним.

Что делать? Меняем querySelector() на querySelectorAll() и получаем искомый массив элементов.

3.2 Почему ошибка undefined и только в первом блоке?

Смотрим на цикл и первая ошибка:

i<=8;

А если блоков будет 7, 9, 250 или 1? Best practice: рассчитывайте количество иттераций исходя из количества элементов массива, с которым работаете. Получаем:

i < filling.length

Обратите внимание, что условие четко “меньше” (<), а не <=.

Это важно т.к.:
а) цикл начинается с 0
б) порядковые номера элементов массива так же начинается с 0

Таким образом когда i === 8 в Вашей реализации filling.innerHTML = firstArr[i], случалось следующее:

filling - первый <div> из верстки
firstArr[8] - undefined т.к. элемента с таким индексом в массиве нет, их всего 7

И именно этот undefined записывался в первый <div>

  1. И почему блок при клике смещается вниз?

Вы искуственно создали высоту и ширину блоков без учета текста в них. Добавьте правило vertical-align: middle; в стили.

THE END

3 лайка