这是我在此处发布的上一个问题的后续问题。我已将其发布在这里,以防万一:How do I alter this function so that only one, random song can be played at a time with each click? (JavaScript)
我正在使用HTML / CSS / JavaScript构建此音乐生成器应用程序,其主要功能是,当用户单击代表音乐流派的特定图块时,该特定流派的一首歌曲就是一次播放。 感谢一些有帮助的SO用户,我能够构建一个可以帮助我做到这一点的功能:
let previousSong;
const randomizeSongs = playlist => {
if (previousSong) {
previousSong.pause();
previousSong.currentTime = 0;
}
let song = playlist[Math.floor(Math.random() * playlist.length)];
song.play();
previousSong = song;
}
const pop = document.querySelector(".pop") // Div containing audio elements
pop.addEventListener("click", (e) => {
let playlist = document.querySelectorAll(".pop audio")
randomizeSongs(playlist);
})
尽管此代码可以很好地工作,但我遇到的一个问题是,尽管歌曲是随机播放的,但即使多次单击,某些歌曲仍会反复播放,而其他歌曲则被忽略。在诸如Spotify或Apple Music之类的应用上,当您随机播放歌曲的播放列表时,歌曲 会随机播放,但是直到播放或跳过其他所有歌曲后,它们才会重复播放。
为解决此问题,我编写了以下代码:
let previousSong;
const randomizeSongs = playlist => {
if (previousSong) {
previousSong.pause();
previousSong.currentTime = 0;
let filteredPlaylist = playlist.filter(function(previousSong) {
return !previousSong;
})
if (filteredPlaylist.length >= 1) {
randomizeSongs(filteredPlaylist);
}
else {
randomizeSongs(playlist);
}
}
let song = playlist[Math.floor(Math.random() * playlist.length)];
song.play();
previousSong = song;
}
我现在遇到了一个新问题。每当我单击代表音乐流派的特定div时,它都会随机选择一首歌曲,但是在第一次单击后每次单击都会使控制台返回:Uncaught TypeError: playlist.filter is not a function at randomizeSongs
。
我对自己做错的事情或我的代码朝正确的方向感到困惑。请帮忙。
答案 0 :(得分:0)
let index = 0;
let previousSong = null;
let randomArray = null;
const randomizeSongs = playlist => {
if(!randomArray) {
toRandom(playlist);
}
if (previousSong) {
previousSong.pause();
previousSong.currentTime = 0;
}
if(index < randomArray.length) {
const song = randomArray[index++];
song.play();
previousSong = song;
}else {
toRandom(playlist);
index = 0;
randomizeSongs(playlist);
}
};
const toRandom = playlist => {
const count = playlist.length;
const playlist_copy = playlist.slice();
randomArray = [];
for(let i = 0; i < count; i++) {
const rand = Math.floor( Math.random() * playlist_copy.length );
randomArray.push(playlist_copy.splice(rand, 1))
}
};
尝试
答案 1 :(得分:0)
您将生成一个包含所有音频元素的数组,并随机播放该数组。然后,在每次单击按钮时逐个循环遍历数组,直到到达末尾时才重新开始随机播放。我会使用randojs.com以一种简单易读的方式对数组进行洗牌。
var playlist = [];
var shuffledPlaylist = [];
var previousSong = false;
function playNextSong(){
if(previousSong){
previousSong.pause();
previousSong.currentTime = 0;
}
if(shuffledPlaylist.length == 0) shuffledPlaylist = randoSequence(playlist);
previousSong = shuffledPlaylist.pop().value;
previousSong.play();
}
window.addEventListener('load', function(){
playlist = document.querySelectorAll(".pop audio");
document.querySelector(".pop").addEventListener("click", playNextSong);
});
如果要使用此代码,请将其包含在html文档的head标签中,以获取randojs功能的源代码:
<script src="https://randojs.com/1.0.0.js"></script>
否则,randoSequence(playlist)
(改组playlist
的函数调用)将不起作用。该代码还使用JavaScript的pop()
function,它删除了shuffledPlaylist
数组的最后一个元素并返回它,因此我们可以将值存储在previousSong
变量中。