Как исправить Uncaught TypeError: невозможно прочитать свойства null (чтение «addEventListener») «loadeddata» в мобильном аудио API

Я следил за этим видео на YouTube https://thewikihow.com/video_1-CvPn4AbT4, чтобы создать мобильный аудиоплеер с плейлистом для встраивания на музыкальный веб-сайт. В 1:12:16 я застрял с чтением ошибки; Uncaught TypeError: Не удается прочитать свойства null (чтение «addEventListener»). Я запустил его в валидаторе js и получил; Функции, объявленные внутри циклов, ссылающиеся на переменную внешней области видимости, могут привести к путанице в семантике. (liAudioTag). Я пытался изменить имя, но не идет. Как я могу это исправить?

Я ни в коем случае не являюсь экспертом в javascript или создании приложений, но я изо всех сил стараюсь учиться. Любая помощь будет оценена по достоинству.

const ulTag = wrapper.querySelector("ul");//1:07:10

for (let i = 0; i < allMusic.length; i++) {
    let liTag = `<li>
                    <div class = "row">
                        <span>${allMusic[i].name}</span>
                        <p>${allMusic[i].artist}</p>
                    </div>
                    <audio class = "${allMusic[i].src}" src = "media/${allMusic[i].src}.mp3"></audio>
                    <span id = "${allMusic[i].src}" class = "audio-duration">3:40</span>
                </li>`;
    ulTag.insertAdjacentHTML("beforeend", liTag);//1:08:28
    
    let liAudioDuaration = ulTag.querySelector(`#${allMusic[i].src}`);//1:10:34
    let liAudioTag = ulTag.querySelector(`.${allMusic[i].src}`);//1:11:29
    
    liAudioTag.addEventListener("loadeddata", ()=>{
        let audioDuration = liAudioTag.duration;    
        let totalMin = Math.floor(audioDuration / 60);
        let totalSec = Math.floor(audioDuration % 60);
        if (totalSec < 10){//add 0 if sec less then 10
          totalSec = `0${totalSec}`;
        }
        liAudioDuaration.innerText = `${totalMin}:${totalSec}`;
    });
    
}

Также; да, я вижу, что liAudioDuaration написано неправильно, но это не имеет значения.

mim 20.11.2022 19:56

«Я запустил его в валидаторе js и получил: функции, объявленные в циклах, ссылающихся на переменную внешней области видимости, могут привести к запутанной семантике». - похоже, вы поместили код в линтер, который не поможет вам с этой ошибкой. Предупреждение о функциях в циклах не имеет значения - оно не имеет ничего общего с ошибкой, которую вы получаете, и нет проблем с определением прослушивателя событий в цикле в вашем коде, поскольку вы используете объявления let (const будет даже лучше).

Bergi 20.11.2022 21:25

«TypeError: Cannot read properties of null (reading ‘addEventListener’)» означает, что liAudioTag является null, потому что ulTag.querySelector(`.${allMusic[i].src}`) вернул null. Отладьте, какой селектор вы использовали. Покажите нам, что такое значение allMusic[i].src — скорее всего, это недопустимое значение атрибута класса, а также недопустимый селектор.

Bergi 20.11.2022 21:27

Спасибо за ответ. Я не был уверен, получу ли я его. Итак, ваш ответ полезен, но, как я уже сказал, я новичок, но пытаюсь учиться. Я не научился «Отлаживать», но, может быть, это то, о чем вы просите?

mim 20.11.2022 21:35

** let allMusic = [ { name: "1. Причины причин", artist: "Jeff Jirout", img: "4_ev_run", src: "Causes of the Causes" }, { name: "3. Forever On The Беги", исполнитель: "Джефф", изображение: "AJWslowroll", источник: "Forever On The Run" } ] **

mim 20.11.2022 21:35

О да. Forever On The Run не очень хорошее название класса - это несколько классов. И .Forever On The Run не выберет ваш элемент. Не используйте произвольные значения в HTML. Вместо этого используйте индекс i в качестве правильного идентификатора, например <audio id = "audio${i}">… <span id = "duration${i}">…, затем document.getElementById("audio"+i)

Bergi 20.11.2022 21:41

вау... БОЛЬШОЕ СПАСИБО. Я смотрел на это в течение нескольких дней. Я удалил пробелы в разделе allMusuc, и теперь он работает как шарм. Ваш спасатель жизни. Хорошего курортного сезона. ваше здоровье

mim 20.11.2022 21:47

Берги, могу я дать тебе значок или что-то в этом роде за помощь?

mim 20.11.2022 21:52

Я изменил #duration${i} и #audio${i}, а также идентификатор звука вместо класса, и все работает отлично. Еще раз спасибо Берги.

mim 20.11.2022 22:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
9
480
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использование src аудиофайла в качестве идентификатора DOM или имени класса не является хорошей идеей, особенно если оно может содержать пробелы. Тогда вы не можете использовать его через селектор. Я бы рекомендовал просто перечислить их, объединив константу с индексом цикла:

const ulTag = wrapper.querySelector("ul");//1:07:10

for (let i = 0; i < allMusic.length; i++) {
    const liTag = `<li>
                <div class = "row">
                    <span>${allMusic[i].name}</span>
                    <p>${allMusic[i].artist}</p>
                </div>
                <audio id = "audio${i}" src = "media/${allMusic[i].src}.mp3"></audio>
                <span id = "duration${i}" class = "audio-duration">3:40</span>
            </li>`;
    ulTag.insertAdjacentHTML("beforeend", liTag)
    
    const liAudioDuaration = ulTag.querySelector(`#duration${i}`);
    const liAudioTag = ulTag.querySelector(`#audio${i}`);
    
    liAudioTag.addEventListener("loadeddata", () => {
        const audioDuration = liAudioTag.duration;    
        const totalMin = Math.floor(audioDuration / 60);
        let totalSec = Math.floor(audioDuration % 60);
        if (totalSec < 10){//add 0 if sec less then 10
          totalSec = `0${totalSec}`;
        }
        liAudioDuaration.innerText = `${totalMin}:${totalSec}`;
    });
}

Другие вопросы по теме