我正在尝试用JS制作一个计数器。到目前为止,我已经设法取消了,但我现在遇到了一个问题。使用AJAX来记录倒计时时,我无法使其工作。这很奇怪,因为它适用于我的原始文件,但不适用于AJAX调用的php文件。
这很好用: https://jsfiddle.net/6kvp25vv/
我不知道问题是什么。这是HTML页面:
<button onclick="upgrade('meat_max')" id="up_meat_max">+</button>
当我点击按钮时,它会运行此js文件中的函数,该函数会在upgrade.php上创建一个GET请求:
function upgrade(building) {
var file = 'upgrade.php?building=' + building;
ajax(file, function(response) {
document.getElementById('construction').innerHTML += response;
})
}
function ajax(file, fn) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
fn(xmlhttp.responseText);
}
};
xmlhttp.open('GET', file, true);
xmlhttp.send();
}
这是来自upgrade.php的代码(使用AJAX发送到此文件的变量不用于测试代码):
<div class="time">Time: <span id="timer">?</span></div>
var hour = 2;
var minute = 46;
var second = 45;
// function to make a counter
function clockIt() {
function clockO(digit) {
if(digit<10) {
return '0';
} else {
return '';
}
}
document.getElementById('timer').textContent = hour + ':' + clockO(minute) + minute + ':' + clockO(second) + second;
if(second>0) {
second -= 1;
} else if(minute>0) {
minute -= 1;
second += 59;
} else if(hour>0) {
hour -= 1;
minute += 59;
}
}
// runs the function every seconds
clockIt();
setInterval(function (){clockIt()}, 1000);
答案 0 :(得分:2)
innerHTML不执行ajax加载的脚本,在你的情况下我会做的是返回一个带有你需要的变量的JSON编码字符串,并在你的主脚本(已经加载的那个)上有一个函数,带有这个提供的脚本那样你已经准备好了函数,只用ajax响应传递参数。
您可以使用以下代码解码json字符串:
obj = JSON.parse(jsonString);
例如:
Ajax JSON响应字符串:
{"time": {"hour":2, "minute":46, "second": 45}, "html": "<div class=\"time\">Time: <span id=\"timer\"></span></div>"}
修改升级功能:
function upgrade(building) {
var file = 'upgrade.php?building=' + building;
ajax(file, function(response) {
obj = JSON.parse(response);
time = obj.time;
document.getElementById('construction').innerHTML += obj.html;
startCountdown(time.hour, time.minute, time.second);
})
}
新功能
function startCountdown(hour, minute, second) {
// function to make a counter
function clockIt() {
function clockO(digit) {
if(digit<10) {
return '0';
} else {
return '';
}
}
document.getElementById('timer').textContent = hour + ':' + clockO(minute) + minute + ':' + clockO(second) + second;
if(second>0) {
second -= 1;
} else if(minute>0) {
minute -= 1;
second += 59;
} else if(hour>0) {
hour -= 1;
minute += 59;
}
}
// runs the function every seconds
clockIt();
setInterval(function (){clockIt()}, 1000);
}
答案 1 :(得分:0)
我的问题在于倒数计时器的方法。当您指定1000毫秒的间隔时,您不能指望它是1000毫秒。实际上,只要定时器循环在1000毫秒过后就到达它,它就会实现。在一段时间内,会有一些延迟。如果您想要准确计时,您想要做的是存储初始设置,然后测量从倒计时开始到当前时间的时间。请参阅下面的代码,该代码基于内部时钟而不是间隔计数器。一旦你有秒数,你可以很容易地将它转换为小时,分钟和秒,然后除以3600小时,并使用除法和模运算分钟和秒。
请参阅https://www.sitepoint.com/creating-accurate-timers-in-javascript/
How to create an accurate timer in javascript?
<!DOCTYPE html />
<html>
<head>
<meta encoding="UTF-8" />
<title>Testing XMLHttpRequest</title>
<script>
var request;
var button1;
var display1;
var display2;
var display3;
var start;
var counter;
function second() {
display2.value = display2.value + "\r\nreadyState=" + request.readyState + " status=" + request.status + "\r\n";;
if (request.readyState == 4 && request.status == 200) {
display1.value = display1.value + request.responseText + "\r\n";
}
}
function first() {
display2.value = display2.value + "\r\n" +
"Starting page \r\n";
request = new XMLHttpRequest();
request.onreadystatechange = second;
var file = "http://localhost:80/";
request.open('GET', file, true);
request.send();
setInterval(timed, 1000);
}
function starter() {
display1 = document.getElementById("display1");
display2 = document.getElementById("display2");
display3 = document.getElementById("display3");
button1 = document.getElementById("button1");
button1.onclick = first;
start = new Date();
counter = 60;
}
function timed() {
var duration = (start.getTime() - new Date().getTime()) / 1000.0;
display3.value = (duration + counter).toFixed(0);
}
window.onload = starter;
</script>
</head>
<body>
<form>
<p>
<input type="button" id="button1" value="Start" />Timer:
<input type="text" readonly="readonly" id="display3" />
</p>
<p>Status:
<textarea rows="5" cols="30" id="display2"></textarea>
</p>
<p>Response:
<textarea rows="60" cols="80" id="display1"></textarea>
</p>
</form>
</body>
</html>
&#13;
答案 2 :(得分:0)
找到一种方法来补偿延迟,使用原始版本:
function upgrade(building) {
var file = 'upgrade.php?building=' + building;
ajax(file, function(response) {
var obj = JSON.parse(response);
var time = obj.time;
document.getElementById('construction').innerHTML += obj.html;
run_clockIt(time.hour, time.minute, time.second);
})
}
// general AJAX launcher
function ajax(file, fn) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
fn(xmlhttp.responseText);
}
};
xmlhttp.open('GET', file, true);
xmlhttp.send();
}
// count down timer with adjustments to compensate delay
function clockIt(hour, minute, second, finished, nbOfLoop) {
// every 5 seconds, run a delay correction
if(nbOfLoop%5 == 0) {
var actualTimeLeft = adjustClock(finished);
minute = actualTimeLeft[0];
second = actualTimeLeft[1];
}
nbOfLoop += 1;
// add a string "0" if necessary
function clockO(digit) {
if(digit<10) {
return '0';
} else {
return '';
}
}
document.getElementById('timer').textContent = hour + ':' + clockO(minute) + minute + ':' + clockO(second) + second;
// update displayed timer
if(second>0) {
second -= 1;
} else if(minute>0) {
minute -= 1;
second += 59;
} else if(hour>0) {
hour -= 1;
minute += 59;
}
// waits 1 sec before launching the next one
setTimeout(function() {
clockIt(hour, minute, second, finished, nbOfLoop);
}, 1000);
}
// runs the function for the first time
function run_clockIt(hour, minute, second) {
var finished = new Date();
finished.setUTCHours(finished.getUTCHours() + hour);
finished.setUTCMinutes(finished.getUTCMinutes() + minute);
finished.setUTCSeconds(finished.getUTCSeconds() + second);
clockIt(hour, minute, second, finished, 1);
}
function adjustClock(finished) {
var now = new Date();
var diff = new Date(Math.abs(now - finished));
return [diff.getUTCMinutes(), diff.getUTCSeconds()];
}
这样,倒计时器是平滑的,没有滞后,最重要的是你可以定义调整功能运行的时间间隔并纠正计时器。
这是php文件,准备JSON对象(感谢@Miguel):
<?php
header('Content-Type: application/json');
// retreive variables from AJAX call
$building = $_REQUEST['building'];
// processing variable with database...
// prepare JSON object
$jsonData = '
{
"time":{"hour":2, "minute":46, "second": 45},
"html": "<div class=\"time\">Time: <span id=\"timer\"></span></div>"
}
';
echo $jsonData;