使用setinterval不断点击Id

id constantly being clicked using setinterval

本文关键字:Id 断点 setinterval 使用      更新时间:2023-09-26

我正在创建一个音频网络播放器,我想连续工作,这意味着当一个音频完成播放,它移动到播放下一个。

然而,我遇到了一个问题,一切都正常工作,但是一旦以前的音频完成播放,下一个开始,每2秒,新的将播放&暂停;连续 .

这是我当前的JavaScript代码块:

function playPauseButton(button, wave, trackID){
    var button = $(button); // play button
    if(wave.isPlaying()){ // if the audio is playing and the user clicks play button, pause the audio
        button.removeClass("playing");
        wave.pause();
    } else { // vice versa
        button.addClass("playing");
        wave.play();
    }
    waveDuration = wave.getDuration(); // audio duration
    var nextTrack = ++trackID; // get the current audio track ID and plus 1 to get the new track ID
    setInterval(function(){ // check every 2 seconds if the audio is finished playing
        if(wave.getCurrentTime() >= waveDuration){ // if it has, make the play button a pause button
            button.removeClass("playing");
            $(nextTrack + '-ppbutton').click(); // simulate new track play button click
        }    
    }, 2000);
}

,我的非常简单的HTML播放按钮:

<!-- onclick play audio (if paused), pause audio (if playing) !-->
<div onclick="playPauseButton(this, a2wave, 2);" id="2-ppbutton"></div>
<!-- 2 is the id !-->

我已经试着弄清楚这几个小时了,然而,它仍然让我困惑(我不擅长JavaScript)

所有帮助&欢迎提出建议。

我试着评论每件事来帮助你理解

:

感谢Vlaz解决我的问题;非常感谢!:)

但是,如果人们仍然想提出建议或编辑,我们也非常欢迎!

谢谢。

问题

你的setInterval的使用将启动一个新的行情时间按下按钮。三次印刷之后,就有三台在运行。此外,请记住,每个人都将运行自己的检查。所以我相信我知道你的问题在哪里,这里是一个概述

    第一次调用
  1. setInterval,记为intervalPrime。让我们假设这首歌的持续时间是60秒。
  2. 歌曲继续,每2秒检查一次,最终结束。
  3. 当播放按钮被点击时,一个新的setInterval被调用——这创建了一个新的间隔——让我们叫它intervalSecond。这将检查一个新的歌曲和新的持续时间,但细节是不相关的。
  4. 播放歌曲,intervalSecond监视是否完成。
  5. 与此同时intervalPrime仍在进行检查。由于wave.getCurrentTime()可能返回60(歌曲结束),那么它所做的检查是通过的60 >= 60,因此它单击按钮。

如何避免

删除旧的间隔

你能做的就是确保一次只有一个setInterval是活动的。该函数返回计时器的ID,因此您可以执行类似于

的操作
var currentChecker;
function playPause() {
   /* .... */
   if (shouldClick) {
     clearTimeout(currentChecker);
     currentChecker = setInterval( /* ... */ );
   }
}

(说明)

因此,在开始一个新的间隔之前,尝试通过停止前一个间隔来保持单个间隔。

只保留一个间隔

另一种选择是只有一个活动间隔并保持一个状态,因此您可以使用像

这样的内容
var masterLoop = setInterval(function() {
    var wave = getCurrentWave(); //fetching it will depend on your application
     if(wave.getCurrentTime() >= wave.getDuration()){
          /* handle what happens */
     }
} , 2000);

当歌曲结束时使用setInterval

我不熟悉你用来播放声音的API,但如果有可能挂钩到结束事件,你可能能够使用简单的setTimeout时,发生,像这样

  //assuming the API allows to do something like this
  wave.onFinish(function() {
      setInterval(playNext, 2000);
  })

如果API没有提供挂钩到完成播放事件的方法,那么更好的选择是将后两者结合起来。有一个主循环,检查轨道的状态,当完成时,使用setInterval来安排下一首歌。间隔延迟可能需要设置得更低,但它会导致音轨之间的时间更一致,因为歌曲可能会在0.3秒后结束,间隔检查并播放歌曲,或者歌曲可能会在间隔结束后结束,所以你会有2秒的间隔。

维护单个setTimeout

这与第一个清除旧间隔的建议相似,但不完全相同。

问题是,你不需要不断检查歌曲是否已经结束播放,因为你已经知道何时将结束。所以,当它播放时,你可以使用setTimeout来为下一首歌排队
//assuming wave returns time in milliseconds
var playNextIn = (wave.getDuration() - wave.getCurrentTime()) + 2000;
nextSongTimer = setTimeout(function() {
    /* code to play next song */
}, playNextIn);

所以,这样你就不需要一直检查。

然而,唯一的问题是,如果用户单击pause,在这种情况下,您将需要调用clearInterval(nextSongTimer),因为它不再需要。因此,这样一来,您只需要在每次播放歌曲时启动计时器。

每次点击播放/暂停按钮,调用setInterval。所以你可能同时有几个基于时间的触发条件可能一直为真。

如果您将对setInterval的调用替换为:

var trigger = setInterval(function(){ // check every 2 seconds if the audio is finished playing
        if(wave.getCurrentTime() >= waveDuration){ // if it has make the play button, a pause button
            button.removeClass("playing");
            $(nextTrack + '-ppbutton').click(); // simulate new track play button click
            clearInterval(trigger);
        }    
    }, 2000);