gpt4 book ai didi

javascript - 多次停止和启动时,计时器功能无法正常工作

转载 作者:可可西里 更新时间:2023-11-01 01:43:41 25 4
gpt4 key购买 nike

首先,您可以在 JS Fiddle 中找到我的代码示例以及问题下方。

我正在开发一个个人培训网络应用程序,基本上您可以点击播放,然后您有五分钟的时间以随机顺序执行一系列任务。该程序创建了 sessionTasks 数组,其中为 tasks 数组放置了随机顺序的任务,以适应五分钟的限制。现在,tasks 数组只是我创建的一个数组,其中包含四个任务和各自的时间,仅用于测试。

我遇到的问题是这样的:当你点击任务让你可以前进到下一个任务时,下一次你玩秒会移动得更快。我发现复制的方式是:

  1. 点击播放。
  2. 通过快速点击任务文本来快速完成任务。
  3. 再次点击播放。

现在秒数应该更快了。如果没有,重复你刚才做的。这是不规则的,但通常会在第二次尝试时出现。

我一辈子都无法理解为什么它会这样。我想也许它正在创建更多的计时器,它们都使用 #taskTimer 来运行,但这对我来说没有意义。 Timer 函数有问题吗?我的代码有什么问题?

mainMenu();


var totalSessionTasks, taskIterator, selectedTimeInSecs = 300;

var taskTimer = new Timer("#taskTimer", nextTask);

var globalTimer = new Timer("#globalTimer", function() {

});

var tasks = [
["First task", 0, 30],
["Second task", 0, 15],
["Third task", 0, 10],
["Fourth task", 3, 0]
];

var sessionTasks = [

]




function setUpSession() {

sessionTasks = []

if (tasks.length != 0) {

var sessionTasksSeconds = 0; //the seconds of the session being filled
var sessionTasksSecondsToFill = selectedTimeInSecs; //seconds left in the session to fill
var newTaskSeconds = 0; //seconds of the next task being added to the session
var sessionFull = false;

console.log('Session Empty');

while (sessionFull === false) {

var areThereAnyTaskThatFitInTheSession =
tasks.some(function(item) {
return ((item[1] * 60 + item[2]) <= sessionTasksSecondsToFill) && (item != sessionTasks[sessionTasks.length - 1]);
});
console.log(areThereAnyTaskThatFitInTheSession);

if (areThereAnyTaskThatFitInTheSession) {
do {
var randTaskNum = Math.floor(Math.random() * tasks.length);
} while (((tasks[randTaskNum][1] * 60 + tasks[randTaskNum][2]) > sessionTasksSecondsToFill) || (tasks[randTaskNum] == sessionTasks[sessionTasks.length - 1]))

sessionTasks.push(tasks[randTaskNum]);
newTaskSeconds = (tasks[randTaskNum][1]) * 60 + tasks[randTaskNum][2];
sessionTasksSecondsToFill -= newTaskSeconds;
sessionTasksSeconds += newTaskSeconds;

console.log(tasks[randTaskNum][0] + ": " + newTaskSeconds + "s");
console.log(sessionTasksSeconds)

} else if (sessionTasks.length == 0) {
note("All your tasks are too big for a game of " + selectedTimeInSecs / 60 + " minutes!");
break;
} else {
console.log('Session full');
sessionFull = true;
taskIterator = -1;
totalSessionTasks = sessionTasks.length;
console.log(totalSessionTasks);

globalTimer.set(0, sessionTasksSeconds);
nextTask();
globalTimer.run();
taskTimer.run();
}


}

} else {
note("You don't have have any tasks in your playlists!");
}

}


function nextTask() {

if (taskIterator + 1 < totalSessionTasks) {
taskIterator++;
$("#taskText").text(sessionTasks[taskIterator][0]);
globalTimer.subtract(0, taskTimer.getTotalTimeInSeconds())
taskTimer.set(sessionTasks[taskIterator][1], sessionTasks[taskIterator][2]);
$("#taskCounter").text(taskIterator + 1 + " of " + totalSessionTasks + " tasks");
} else {
mainMenu();
taskTimer.stop();
globalTimer.stop();
note("Thanks for playing!");
}


}

//timer object function
function Timer(element, callback) {

var ac, minutes, seconds, finalTimeInSeconds, displayMinutes, displaySeconds, interval = 1000,
self = this,
timeLeftToNextSecond = 1000;
this.running = false;

this.set = function(inputMinutes, inputSeconds) {

finalTimeInSeconds = inputMinutes * 60 + inputSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;

this.print();
}

this.add = function(inputMinutes, inputSeconds) {

finalTimeInSeconds += inputMinutes * 60 + inputSeconds;
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;

this.print();
}

this.subtract = function(inputMinutes, inputSeconds) {

finalTimeInSeconds -= inputMinutes * 60 + inputSeconds;
if (finalTimeInSeconds <= 0) {
callback()
}
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}

this.reset = function() {

this.set(0, 0);
}

this.print = function() {

displayMinutes = (minutes.toString().length == 1) ? "0" + minutes : minutes; //ternary operator: adds a zero to the beggining
displaySeconds = (seconds.toString().length == 1) ? "0" + seconds : seconds; //of the number if it has only one caracter.

$(element).text(displayMinutes + ":" + displaySeconds);
}

this.run = function() {

if (this.running == false) {
this.running = true;

var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
interval = 1000;
}
ac = setInterval(_f, interval);


}
}

this.stop = function() {

if (this.running == true) {
this.running = false;
console.log(this + "(" + element + ") was stopped");
stopped = new Date;
interval = 1000 - (stopped - secondStarted);
clearInterval(ac);
}
}

this.getTotalTimeInSeconds = function() {


return finalTimeInSeconds;
}

this.reset();

}

function note(string) {
alert(string);
}

function mainMenu() {
//EMPTY BODY
$("body").empty();
$("body").append(
//BUTTONS
"<div id='playButton' class='mainButton'><div class='buttonText mainButtonText'>PLAY</div></div>"
);
//BINDS
$("#playButton").bind("click", function(){
playMain();
setUpSession();
});

}

function playMain() {
//EMPTY BODY
$("body").empty();
$("body").append(
//TASK TEXT
"<p class='text' id='taskText'>Lorem ipsum dolor sit amet.</p>",
//TIMERS
"<div id='taskTimerWrap'><p class='text timer' id='taskTimer'>00:00</p><p class='text' id='taskTimerText'>Task Time</p></div>",
"<div id='globalTimerWrap'><p class='text timer' id='globalTimer'>00:00</p><p class='text' id='globalTimerText'>Global Time</p></div>",
//TASK COUNTER
"<div class='text' id='taskCounter'>0/0 tasks completed</div>"
);
//BINDS
$("#taskText").bind("click", nextTask);
}
#taskText {
text-align: center;
display: table;
vertical-align: middle;
height: auto;
width: 100%;
top: 50px;
bottom: 0;
left: 0;
right: 0;
position: absolute;
margin: auto;
font-size: 65px;
cursor: pointer;
}

#taskTimerWrap {
text-align: center;
top: 0;
right: 0;
left: 170px;
margin: 5px;
position: absolute;
-webkit-transition: all 0.5s ease;
}

.timer {
font-size: 64px;
margin: 0;
line-height: 0.88;
}

#taskTimerText {
font-size: 34.4px;
margin: 0;
line-height: 0.65;
}

#globalTimerWrap {
text-align: center;
top: 0;
left: 0;
right: 170px;
margin: 5px;
position: absolute;
}

#globalTimerText {
font-size: 28.5px;
margin: 0;
line-height: 0.78;
transform: scale(1, 1.2);
}

#taskCounter {
text-align: center;
bottom: 0;
right: 0;
left: 0;
width: auto;
position: absolute;
font-size: 30px;
color: #98D8D9;
-webkit-transition: all 0.5s ease;
}

#taskCounter:hover {
color: #F1F2F0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

最佳答案

Timer.stop() 中,您可以更改用于下一次运行的间隔。更改 _f() 中的间隔变量不会更改 setInterval() 使用的间隔。

在这种情况下,您将不得不使用 setTimeout() 代替:

function Timer(element, callback) {    
var ac, minutes, seconds, finalTimeInSeconds, displayMinutes, displaySeconds, timeout = 1000,
self = this,
timeLeftToNextSecond = 1000;
this.running = false;

/* ... */

this.run = function() {
if (this.running == false) {
this.running = true;

var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
ac = setTimeout(_f, 1000);
}
ac = setTimeout(_f, timeout);
}
}

this.stop = function() {
if (this.running == true) {
this.running = false;
console.log(this + "(" + element + ") was stopped");
stopped = new Date;
timeout = 1000 - (stopped - secondStarted);
clearTimeout(ac);
}
}

/* ... */
}

关于javascript - 多次停止和启动时,计时器功能无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34484386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com