簡體   English   中英

為什么事件被多次觸發?

[英]Why event is triggered more than once?

我正在嘗試使用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");
        }

唯一的問題是,每首歌曲結束時,都會多次觸發“結束”事件。 在“結束”事件之后,將執行該函數,然后再次執行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建議的那樣。

您在聽眾內部調用歌曲播放,這將在另一時間....另一時間和另一時間應用它。

遞歸。

>_>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM