我正在尝试使用SoundManager2为音频Javascript插件添加事件处理程序。这是播放歌曲并等待歌曲结束再次执行该功能的功能:
function songPlay (newSrc) {
htmlSound.src = newSrc;
htmlSound.load();
thisPlayer.find( ".total-position-scrubber" ).bind( "slide", function(event, ui) {
htmlSound.currentTime = ui.value;
});
var currentArtist = currentRow.find(".total-artist").text();
var currentTitle = currentRow.find(".total-title").text();
thisPlayer.find(".total-playing-artist").html(currentArtist);
thisPlayer.find(".total-playing-title").html(currentTitle);
htmlSound.addEventListener("timeupdate", function() {
var newVolume = thisPlayer.find( ".total-volume-slider" ).slider("option", "value");
htmlSound.volume = newVolume;
var duration = htmlSound.duration * 1000;
var durationTime = convertMilliseconds(duration, "mm:ss");
thisPlayer.find(".total-song-duration").html(durationTime.clock );
var position = htmlSound.currentTime * 1000;
var positionTime = convertMilliseconds(position, "mm:ss");
thisPlayer.find(".total-song-position").html(positionTime.clock );
thisPlayer.find( ".total-position-scrubber" ).slider("option", "max", duration/1000);
thisPlayer.find( ".total-position-scrubber" ).slider("option", "value", position/1000);
});
htmlSound.addEventListener("ended", function() {
// Find next checked song
currentRow = currentRow.nextAll(".can-play:first");
// If checked song exists after current song, load it
if(currentRow.length > 0)
{
var newSrc = currentRow.find("[src]").attr("src");
songPlay(newSrc);
}
else
{
// If no checked song exists after current song, load the first checked song in playlist
if(thisPlayer.find(".can-play").length > 0)
{
currentRow = thisPlayer.find(".can-play:first");
var newSrc = currentRow.find("[src]").attr("src");
songPlay(newSrc);
}
// Change pause button to play button
else
{
thisPlayer.find(".total-play").removeClass("total-pause");
}
}
// If song is playing while next button is clicked play next song
if(thisPlayer.find(".total-pause").length > 0)
{
htmlSound.play();
}
});
thisPlayer.find(".total-row .total-not-playing").removeClass("total-playing");
currentRow.find(".total-not-playing").addClass("total-playing");
}
唯一的问题是"结束"每次歌曲结束时,事件会被触发多次。在"结束后#34; event,执行函数,然后再次执行songPlay()
函数(这是预期的行为),然后,"结束"在歌曲结束之前,事件再次被触发,而它应该等待歌曲的结束。知道这种行为的原因吗?
newSrc
变量始终是正确的值。
这是"结束" SoundManager2中的事件定义:
_html5_events = {
// HTML5 event-name-to-handler map
...
ended: _html5_event(function() {
var t = this._t;
_s._wD(_h5+'ended: '+t.sID);
t._onfinish();
}),
...
}
修改
令人惊讶的是,它只是用声明的函数替换匿名函数,如下所示:
function eventListenerFunction() {
// Find next checked song
currentRow = currentRow.nextAll(".can-play:first");
// If checked song exists after current song, load it
if(currentRow.length > 0)
{
var newSrc = currentRow.find("[src]").attr("src");
songPlay(newSrc);
}
else
{
// If no checked song exists after current song, load the first checked song in playlist
if(thisPlayer.find(".can-play").length > 0)
{
currentRow = thisPlayer.find(".can-play:first");
var newSrc = currentRow.find("[src]").attr("src");
songPlay(newSrc);
}
// Change pause button to play button
else
{
thisPlayer.find(".total-play").removeClass("total-pause");
}
}
// If song is playing while next button is clicked play next song
if(thisPlayer.find(".total-pause").length > 0)
{
htmlSound.play();
}
});
function songPlay (newSrc) {
htmlSound.src = newSrc;
htmlSound.load();
thisPlayer.find( ".total-position-scrubber" ).bind( "slide", function(event, ui) {
htmlSound.currentTime = ui.value;
});
var currentArtist = currentRow.find(".total-artist").text();
var currentTitle = currentRow.find(".total-title").text();
thisPlayer.find(".total-playing-artist").html(currentArtist);
thisPlayer.find(".total-playing-title").html(currentTitle);
htmlSound.addEventListener("timeupdate", function() {
var newVolume = thisPlayer.find( ".total-volume-slider" ).slider("option", "value");
htmlSound.volume = newVolume;
var duration = htmlSound.duration * 1000;
var durationTime = convertMilliseconds(duration, "mm:ss");
thisPlayer.find(".total-song-duration").html(durationTime.clock );
var position = htmlSound.currentTime * 1000;
var positionTime = convertMilliseconds(position, "mm:ss");
thisPlayer.find(".total-song-position").html(positionTime.clock );
thisPlayer.find( ".total-position-scrubber" ).slider("option", "max", duration/1000);
thisPlayer.find( ".total-position-scrubber" ).slider("option", "value", position/1000);
});
htmlSound.addEventListener("ended", eventListenerFunction)
thisPlayer.find(".total-row .total-not-playing").removeClass("total-playing");
currentRow.find(".total-not-playing").addClass("total-playing");
}
但是,我想我应该在触发函数之后使用$('body').off("ended")
删除事件监听器,正如@Fallenreaper建议的那样。
答案 0 :(得分:1)
你在一个听众中调用歌曲,然后再将它应用于另一个时间....另一个时间和另一个时间。
递归。
>_>