Dynamic Audio Widgets playing same audio

Advertisements

Here is a simplified version of my web page – all buttons are playing the first element in the array and I don’t know why. I suspect it’s something to do with the forEach loop not functioning in the correct way

// Listen Page
audioItems = [
'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/alien_hit.wav',
'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/alien_shoot.wav',
'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/bonus.wav',
]

const listenContainer = document.querySelector('.audio-widget-container');

audioItems.forEach(track => {
    newTrackWidget = document.createElement('div');
    newTrackWidget.classList.add('track-container')

    trackTitle = document.createElement("h3");
    trackTitle.textContent = track;

    trackButton = document.createElement("button");
    trackButton.innerHTML = `<i class="fa-solid fa-play"></i>`
    trackTimeline = document.createElement("div");

    trackAudio = document.createElement("audio");
    trackAudio.src = track;

    trackButton.addEventListener("click", () => {
        trackAudio.play()
    })

    newTrackWidget.appendChild(trackAudio)
    newTrackWidget.appendChild(trackTitle);
    newTrackWidget.appendChild(trackButton);
    newTrackWidget.appendChild(trackTimeline);

    listenContainer.appendChild(newTrackWidget);
});
<script src="https://kit.fontawesome.com/00c3160031.js" crossorigin="anonymous"></script>

<section class="audio-widget-container">
</section>

>Solution :

You assigned to variables without keywords, which mean that they are hoisted to global scope. To fix it create new variables inside forEach loop using keyword let:

const audioItems = [
    'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/alien_hit.wav',
    'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/alien_shoot.wav',
    'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/bonus.wav',
];

const listenContainer = document.querySelector('.audio-widget-container');

audioItems.forEach(track => {
    let newTrackWidget = document.createElement('div');
    newTrackWidget.classList.add('track-container');

    let trackTitle = document.createElement('h3');
    trackTitle.textContent = track;

    let trackButton = document.createElement('button');
    trackButton.innerHTML = `<i class="fa-solid fa-play"></i>`;
    let trackTimeline = document.createElement('div');
    let trackAudio = document.createElement('audio');
    trackAudio.src = track;

    trackButton.addEventListener('click', () => {
        trackAudio.play();
    });

    newTrackWidget.appendChild(trackAudio);
    newTrackWidget.appendChild(trackTitle);
    newTrackWidget.appendChild(trackButton);
    newTrackWidget.appendChild(trackTimeline);

    listenContainer.appendChild(newTrackWidget);
});
<script src="https://kit.fontawesome.com/00c3160031.js" crossorigin="anonymous"></script>

<section class="audio-widget-container">
</section>

Leave a Reply Cancel reply