持续时间不适用于所有行
我创建了一个与Spotify类似的音乐列表是JavaScript,我试图在所有行中添加持续时间,但问题是持续时间仅适用于第一行。控制台不显示任何错误。我尝试过,但无法弄清楚是什么问题。
// Creating Music List
const tbody = document.querySelector("tbody");
// let create tr tags according to array length for list
for (let i = 0; i < songs.length; i++) {
//let's pass the song details from the array
let trTag = `<tr tr-index = ${i}>
<td class="numberlist" width="5%">${songs[i].nmbr}</td>
<td class="title" width="80%">
<div>
<img class="cover1" src=${songs[i].coverPath} >
</div>
<div class="songdetails">
<h3>${songs[i].trackName}</h3>
<h4>${songs[i].trackArtist}</h4>
</div>
</td>
<td width="30%">
<h4>${songs[i].trackAlbum}</h4>
</td>
<td width="15%">${songs[i].date}</td>
<td width="5%">
<img class="svg1" src="/assets/asset 72.svg" alt="">
</td>
<td width="12%" class="audio_duration">0:00</td>
</tr> `;
tbody.insertAdjacentHTML("beforeend", trTag); //inserting the tr inside tbody tag
let trAudioDuration = tbody.querySelector(".audio_duration");
let trAudioTag = new Audio(`audio/1.mp3`);
trAudioTag.addEventListener("loadeddata", () => {
let aDuration = trAudioTag.duration;
let totalMin = parseInt(aDuration / 60);
let totalSec = parseInt(aDuration % 60);
if (totalSec < 10) {
totalSec = `0${totalSec}`;
};
trAudioDuration.innerHTML = `${totalMin}:${totalSec}`; //passing total duration of song
});
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
啊,这是一个经典的!问题在于:
请参阅,
querySelector
,尤其是在使用类选择器时,仅返回第一个匹配的元素。我们需要在此处使用queryselectorall
,这返回所有匹配的元素。由于
querySelectorAll
返回多个元素的数组,因此我们还需要对InnerHtml进行一些不同的处理设置,因此我们使用foreach
浏览所有匹配的元素并设置他们每个人都在内。这是一个剪切,证明了问题和解决方案:
在重要的侧面注释您不应使用innerhtml将持续时间写入元素。您的持续时间只是文本,并且包含零HTML,因此,使用
textContent
之类的东西是一个更好的主意。这样可以确保某些恶意聚会没有机会通过以某种方式用html替换持续时间数据,例如&lt; script&gt; arter(“ hax”)&lt;/script;/script&gt;
。请注意,我实际上是如何在那里编写HTML的,但是Stackoverflow进行了考虑,您的浏览器实际上不会为您弹出一个警报框,而仅显示为文本。如果您确实需要使用innerhtml
,请记住Ahh, this is a classic one! The problem lies with this:
See,
querySelector
, especially when using a class selector, only returns the first matched element. We need to usequerySelectorAll
here instead, which returns all of the matched elements.Since
querySelectorAll
returns an array of multiple elements, we also need to handle the innerHTML setting a bit differently, so we useforEach
to go through all of the matched elements and set the innerHTML on each of them.Here's a snipped demonstrating the issue and the solution:
On an important side note you shouldn't use innerHTML to write the duration into the elements. Your duration is just text and contains zero html, so it is a better idea to use something like
textContent
instead. This ensures that some malicious party has no chance of injecting their own bad HTML to your page by somehow replacing duration data with HTML like<script>alert("hax")</script>
. Notice how I actually just wrote HTML there, but StackOverflow has this thought out and your browser won't actually pop an alert box for you and only shows that as a text. If you ever DO need to useinnerHTML
, remember to sanitize it first.您的问题是因为您的选择器
.audio_duration
正在搜索tbody
所有.audio_duration
elements均为。一种解决方案是获取您插入并在此上执行选择器的
tr
,然后在.audio_duration
中查找tr
而不是查找.aud>。
tbody
。Your issue is because your selector
.audio_duration
is searching thetbody
where all the.audio_duration
elements are.One solution would be to get the
tr
that you inserted and perform your selector on that and then it will look for.audio_duration
in thetr
instead of thetbody
.在歌曲数组中添加{src:“ AudiofilEname”},并在下面的修改代码中添加。
** - 修改的代码
adding {src: "audiofilename"} in song array and modifying code like below worked out.
** - modified code
如@swiffy在他的答案由于
toby> toby toby.queryselector(“。
将首先选择.audio_duration
来自tbody
的元素。您可以像以下内容一样更新该查询选择器,它应该很好地工作。
说明:
tr [tr-index ='$ {i}'] .audio_duration
将在tr
element elementtbody 带有属性
tr-index
及其用i
指定的值及其任何孩子(包括儿童的孩子等)具有audio_duration
并使用类audio_duration
返回该元素。tr [tr-index ='$ {i}']音频
将找到tr
elementtbody
tr-index 及其用i
指定的值及其任何孩子(包括儿童的孩子等)audio
元素,然后返回audio
元素。注意: queryselector 将从给定的选择器返回第一个匹配值。如果要获取所有匹配元素,请使用。
参考:
As explained by @Swiffy in his answer problem is there due to
tbody.querySelector(".audio_duration");
as it will select first.audio_duration
element fromtbody
.You can update that query selector like below and it should work well.
Explanation :
tr[tr-index='${i}'] .audio_duration
will findtr
element insidetbody
with attributetr-index
and its value specified withi
and any of its child (including child of child and so on) having classaudio_duration
and return that element with classaudio_duration
.tr[tr-index='${i}'] audio
will findtr
element insidetbody
with attributetr-index
and its value specified withi
and any of its child (including child of child and so on)audio
element and return thataudio
element.Note : querySelector will return first matching value from given selector. If you want to get all matching element then use querySelectorAll.
References :