Я следил за этим видео на 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}`;
});
}
«Я запустил его в валидаторе js и получил: функции, объявленные в циклах, ссылающихся на переменную внешней области видимости, могут привести к запутанной семантике». - похоже, вы поместили код в линтер, который не поможет вам с этой ошибкой. Предупреждение о функциях в циклах не имеет значения - оно не имеет ничего общего с ошибкой, которую вы получаете, и нет проблем с определением прослушивателя событий в цикле в вашем коде, поскольку вы используете объявления let
(const
будет даже лучше).
«TypeError: Cannot read properties of null (reading ‘addEventListener’)» означает, что liAudioTag
является null
, потому что ulTag.querySelector(`.${allMusic[i].src}`)
вернул null
. Отладьте, какой селектор вы использовали. Покажите нам, что такое значение allMusic[i].src
— скорее всего, это недопустимое значение атрибута класса, а также недопустимый селектор.
Спасибо за ответ. Я не был уверен, получу ли я его. Итак, ваш ответ полезен, но, как я уже сказал, я новичок, но пытаюсь учиться. Я не научился «Отлаживать», но, может быть, это то, о чем вы просите?
** 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" } ] **
О да. Forever On The Run
не очень хорошее название класса - это несколько классов. И .Forever On The Run
не выберет ваш элемент. Не используйте произвольные значения в HTML. Вместо этого используйте индекс i
в качестве правильного идентификатора, например <audio id = "audio${i}">… <span id = "duration${i}">…
, затем document.getElementById("audio"+i)
вау... БОЛЬШОЕ СПАСИБО. Я смотрел на это в течение нескольких дней. Я удалил пробелы в разделе allMusuc, и теперь он работает как шарм. Ваш спасатель жизни. Хорошего курортного сезона. ваше здоровье
Берги, могу я дать тебе значок или что-то в этом роде за помощь?
Я изменил #duration${i} и #audio${i}, а также идентификатор звука вместо класса, и все работает отлично. Еще раз спасибо Берги.
Использование 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}`;
});
}
Также; да, я вижу, что liAudioDuaration написано неправильно, но это не имеет значения.