JavaScript MP3播放器手动选歌后无法切换曲目,报substr未定义错误
Hey there! Let's break down why your MP3 player is throwing that error after manually selecting a track—this is a super common gotcha when adding custom playlist interactions, so we'll get it fixed in no time.
First, Let's Understand the Error
The error message tells us exactly where to look:
Uncaught TypeError: Cannot read property 'substr' of undefined at loadSong (player.js:20)
This means on line 20 of player.js, you're trying to call the substr() method on a variable that's undefined. In the context of your player, that variable is almost certainly the song object (or its file path) that loadSong() is trying to process.
Root Cause: Manual Track Selection Isn't Updating Your State
The key clue here is that the player works fine until you manually pick a song. That tells me your manual selection logic isn't properly updating the core state your next()/prev() functions rely on—specifically, the index of the currently playing track in your songs array.
Step-by-Step Fixes
1. Verify Your Manual Selection Logic
When a user clicks a track in your custom list, you need to do two critical things:
- Update the
currentIndexvariable to match the clicked track's position in your songs array - Pass the valid song object to
loadSong()
Here's an example of how that should look (adjust to match your variable names):
// Assume your playlist items have a data-index attribute with their array position const playlistItems = document.querySelectorAll('.mp3-list-item'); playlistItems.forEach(item => { item.addEventListener('click', () => { // Update the current track index currentIndex = parseInt(item.dataset.index); // Load the valid song object from your array loadSong(songs[currentIndex]); }); });
If you're only setting the audio source directly without updating currentIndex, your next()/prev() functions will use an outdated index and try to access a non-existent song (hence undefined).
2. Double-Check Your next()/prev() Functions
Make sure these functions correctly calculate the new index and never go out of bounds of your songs array:
function next() { currentIndex++; // Loop back to the first track if we reach the end if (currentIndex >= songs.length) { currentIndex = 0; } // Ensure we're passing a valid song object loadSong(songs[currentIndex]); } function prev() { currentIndex--; // Loop to the last track if we go below 0 if (currentIndex < 0) { currentIndex = songs.length - 1; } loadSong(songs[currentIndex]); }
3. Add Defensive Checks to loadSong()
To prevent similar errors in the future, add a quick check at the start of loadSong() to ensure you're working with a valid song object:
function loadSong(song) { // Bail early if the song object or its file path is missing if (!song || !song.file) { console.error('Failed to load song: invalid song object', song); return; } // Your existing logic (including the substr() call) goes here }
Wrap-Up
The core issue is that your manual track selection wasn't syncing up with the currentIndex your navigation functions depend on. Once you update that index when a user clicks a track, next()/prev() will know exactly which song to load next, and that substr() error will disappear.
内容的提问来源于stack exchange,提问作者Tom Rassaerts

