Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.07.2020, 13:19
Аспирант
Отправить личное сообщение для Vahan60 Посмотреть профиль Найти все сообщения от Vahan60
 
Регистрация: 20.04.2020
Сообщений: 46

Выдает TypeError, но при этом работает штатно.
Всем доброго времени суток.
Ниже приведен фрагмент кода азбуки.
let dial = document.getElementById("dial");
let but = document.getElementById("but");
let img = document.querySelectorAll(".img");

let activeUnit;

for (let i = 0; i < alphabet.length; i++){
      unit[i].addEventListener("click", function() {
	  activeUnit = i;
      dial.show();
   for (let j = 0; j < 3; j++) {
	  img[j].src = "cartoons/".concat(inset[activeUnit][j].concat(".png"))
          }
	  })   
   };  

 but.addEventListener("click", function() {
      dial.close();
});

let small = document.querySelectorAll(".small");
let sound = document.createElement("audio");

for (let j = 0; j < alphabet.length; j++){
      small[j].addEventListener ("click", function(){ // [B]Uncaught TypeError: Cannot read property 'addEventListener' of undefined [/B]
	  sound.src = "audio/".concat(inset[activeUnit][j].concat(".mp3")); 
	  sound.play()
	  })   
   };

Скрипт работает штатно, делает то, что и планировалось:

1. по клику на букву
1.1 выводит на экран диалоговое окно;
1.2 размещает в нем 3 картинки;
2. по клику на картинку озвучивает что на ней нарисовано;
3. по клику на "Х" закрывает диалоговое окно.

И далее по кругу.

Вот только "есть ньюанс". Даже 2 ньюанса.

Первый: на строке 25 выдает "Uncaught TypeError: Cannot read property 'addEventListener' of undefined ". Какой такой эррор-меррор?! Код же работает.

Второй: при клике на первую букву азбуки (сразу после открытия программы в браузере), допустим "А", все работает нормально. А вот после закрытия диалогого окна и после клика на вторую букву, допустим "Б", диалоговое окно "мигает". То есть: на мгновение открываются картинки соответствующие букве "А" и только затем показываются картинки буквы "Б".

Подскажите, пожалуйста, в чем дело.
Ответить с цитированием
  #2 (permalink)  
Старый 05.07.2020, 15:10
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Vahan60,
скорее всего количество букв и элементов для них не совпадает.
alert([alphabet.length, small.length])
Ответить с цитированием
  #3 (permalink)  
Старый 05.07.2020, 15:39
Аспирант
Отправить личное сообщение для Vahan60 Посмотреть профиль Найти все сообщения от Vahan60
 
Регистрация: 20.04.2020
Сообщений: 46

Для размещения азбуки на странице я создал (через JS) таблицу 8Х5=40 <th>. Присвоил им th.className = "unit". А букв 38.
Это может быть причиной?
Что же, мне создавать таблицу через HTML, а не через JS?
Ответить с цитированием
  #4 (permalink)  
Старый 05.07.2020, 15:43
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Vahan60,
Ответить с цитированием
  #5 (permalink)  
Старый 05.07.2020, 15:45
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Сообщение от Vahan60
Это может быть причиной?
причина указана выше.
Сообщение от Vahan60
Что же, мне создавать таблицу через HTML, а не через JS?
бред какой-то.
Ответить с цитированием
  #6 (permalink)  
Старый 05.07.2020, 16:59
Аспирант
Отправить личное сообщение для Vahan60 Посмотреть профиль Найти все сообщения от Vahan60
 
Регистрация: 20.04.2020
Сообщений: 46

Почему бред?
Сами же написали: "скорее всего количество букв и элементов для них не совпадает.
alert([alphabet.length, small.length])"


Моя вина, наверное JS код надо было приводить полностью, а не фрагментарно. Вот код полностью.
let elem = document.querySelector('#elem');
createTable(elem, 8, 5);

function createTable(parent, cols, rows) {
	let table = document.createElement('table');
	
	for (let i = 0; i < rows; i++) {
		let tr = document.createElement('tr');
		
		for (let j = 0; j < cols; j++) {
			let th = document.createElement('th');
			th.className = "unit";
			tr.appendChild(th)
		};
		table.appendChild(tr)
	};
	parent.appendChild(table)
};

const alphabet = ["Ա", "Բ", "Գ", "Դ", "Ե", "Զ", "Է", "Ը", "Թ", "Ժ", "Ի", "Լ", "Խ", "Ծ", "Կ", "Հ", "Ձ", "Ղ", "Ճ", "Մ", "Յ", 
                  "Ն", "Շ", "Ո", "Չ", "Պ", "Ջ", "Ռ", "Ս", "Վ", "Տ", "Ր", "ՈՒ", "Փ", "Ք", "և", "Օ", "Ֆ"];
				  
const inset = [["aghves", "apse", "ator"], ["gndak", "gile", "gdal"], ["2.0", "2.1", "2.2"], 
               ["3.0", "3.1", "3.2"], ["4.0", "4.1", "4.2"], ["5.0", "5.1", "5.2"],
               ["6.0", "6.1", "6.2"], ["7.0", "7.1", "7.2"], ["8.0", "8.1", "8.2"],
			   ["9.0", "9.1", "9.2"], ["10.0", "10.1", "10.2"], ["11.0", "11.1", "11.2"], 
               ["12.0", "12.1", "12.2"], ["13.0", "13.1", "13.2"], ["14.0", "14.1", "14.2"], ["15.0", "15.1", "15.2"],
			   ["16.0", "16.1", "16.2"], ["17.0", "17.1", "17.2"], ["18.0", "18.1", "18.2"], ["19.0", "19.1", "19.2"], 
               ["20.0", "20.1", "20.2"], ["21.0", "21.1", "21.2"], ["22.0", "22.1", "22.2"], ["23.0", "23.1", "23.2"],
			   ["24.0", "24.1", "24.2"], ["25.0", "25.1", "25.2"], ["26.0", "26.1", "26.2"], ["27.0", "27.1", "27.2"],
			   ["28.0", "28.1", "28.2"], ["29.0", "29.1", "29.2"], ["30.0", "30.1", "30.2"], ["31.0", "31.1", "31.2"],
			   ["32.0", "32.1", "32.2"], ["33.0", "33.1", "33.2"], ["34.0", "34.1", "34.2"], ["35.0", "35.1", "35.2"],
			   ["36.0", "36.1", "36.2"], ["37.0", "37.1", "37.2"]];     
			   
const unit = document.getElementsByClassName("unit");

for (let i = 0; i < alphabet.length; i++) {
	unit[i].append(alphabet[i])
};

let dial = document.getElementById("dial");
let but = document.getElementById("but");
let img = document.querySelectorAll(".img");
let activeUnit;

for (let i = 0; i < alphabet.length; i++){
      unit[i].addEventListener("click", function() {
	  activeUnit = i;
      dial.show();
   for (let j = 0; j < img.length; j++) {
	  img[j].src = "cartoons/".concat(inset[activeUnit][j].concat(".png"))
          }
	  })   
   };  

 but.addEventListener("click", function() {
      dial.close();
});

let small = document.querySelectorAll(".small");
console.log (small);
let sound = document.createElement("audio");

for (let j = 0; j < alphabet.length; j++){
      small[j].addEventListener ("click", function() {  
	  sound.src = "audio/".concat(inset[activeUnit][j].concat(".mp3")); 
	  sound.play()
	  })   
   };


Как видите, упомянутое вами несоответствие может быть между количеством букв в алфавите const alphabet (38) и количеством ячеек в let elem (40).
Как изменить let elem (40) на let elem (38) через JS, я не знаю.
Зато знаю, как это сделать через HTML.
Ответить с цитированием
  #7 (permalink)  
Старый 06.07.2020, 07:40
Аспирант
Отправить личное сообщение для Vahan60 Посмотреть профиль Найти все сообщения от Vahan60
 
Регистрация: 20.04.2020
Сообщений: 46

Сообщение от рони Посмотреть сообщение
Vahan60,
скорее всего количество букв и элементов для них не совпадает.
alert([alphabet.length, small.length])
рони, вы полностью правы.
Исправил. TypeError пропал. Спасибо.

Осталось исправить "мигание":

"...при клике на первую букву азбуки (сразу после открытия программы в браузере), допустим "А", все работает нормально. А вот после закрытия диалогого окна и после клика на вторую букву, допустим "Б", диалоговое окно "мигает". То есть: на мгновение открываются картинки соответствующие букве "А" и только затем показываются картинки буквы "Б"..."
Ответить с цитированием
  #8 (permalink)  
Старый 06.07.2020, 08:15
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,692

Вы сначала показываете диалог (со старыми картинками),

49 dial.show();

а потом грузите в него новые картинки.

Строки 50-52

Правильнее сначала загружать картинки, дождаться, когда они все будут загружены, а потом показывать диалог.
Ответить с цитированием
  #9 (permalink)  
Старый 07.07.2020, 11:50
Аспирант
Отправить личное сообщение для Vahan60 Посмотреть профиль Найти все сообщения от Vahan60
 
Регистрация: 20.04.2020
Сообщений: 46

Сообщение от voraa Посмотреть сообщение
...

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

for (let i = 0; i < alphabet.length; i++){
    unit[i].addEventListener("click", function() {
    activeUnit = i;
    for (let j = 0; j < img.length; j++) {
	  img[j].src = "cartoons/".concat(inset[activeUnit][j].concat(".png"))
          };
    dial.show()
      })
};

Работает. Но "мигание" не пропало. :(
Ответить с цитированием
  #10 (permalink)  
Старый 07.07.2020, 12:38
Аспирант
Отправить личное сообщение для Vahan60 Посмотреть профиль Найти все сообщения от Vahan60
 
Регистрация: 20.04.2020
Сообщений: 46

По всей видимости тут надо действовать через колбек.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не работает скрипт при подключении другого скрипта Аслан Events/DOM/Window 0 29.04.2017 02:13
Не работает XMLHttpRequest.upload.onprogress при POST запосах Serduko Javascript под браузер 12 05.10.2016 13:14
не работает слайдер при первой загрузки страницы Nailya jQuery 7 08.09.2016 16:33
DatePicker не работает при сипользование innerHTML AJlekceu jQuery 2 26.10.2008 17:49
insertBefore выдаёт ошибку и не работает на опере и фоксе SunnyDay Общие вопросы Javascript 3 19.09.2008 12:08