这里是 Javascript 的新手,经过几个小时挖掘其他问题后,老实说,我不太确定如何解释这个问题,但我会尽力而为,希望你能帮助我。
HTML:
<div id='header'> <h1> Pastel Land </h1> </div>
<div id='container'>
<div id='readyContainer'>
<h3> This game will start in </h3>
<h1 id='readySeconds'> </h1>
</div>
<div id='shape'> </div>
</div>
<div id='features'>
<button id='start'> START </button>
<button id='stop'> STOP </button>
<p id='timeBox'></p>
<p id='timeAverageBox'></p>
</div>
<div id='testbox'> </div>
完整脚本:
document.getElementById('start').onclick = function () {
document.getElementById('readyContainer').style.display = 'block';
document.getElementById('readySeconds').innerHTML = '3'
setTimeout(function() {document.getElementById('readySeconds').innerHTML = '2'}, 1000);
setTimeout(function() {document.getElementById('readySeconds').innerHTML = '1'}, 2000);
setTimeout(readyAlert,3000);
setTimeout(displayShape, 3000);
var style = document.getElementById('shape').style;
var el = document.getElementById('shape');
el.addEventListener("click", a, false);
el.addEventListener("click", b, false);
function a() {
style.display = "none";
displayShapeDelay(); // calls the delay function
}
function b() {
end = new Date().getTime(); // saves time when clicked
var time = (end - start)/1000 ; // calculates interval from shape creation until click
document.getElementById('timeBox').innerHTML = time + 's';
return time;
}
document.getElementById('testbox').innerHTML = b();
function readyAlert() {
document.getElementById('readyContainer').style.display = 'none';
}
function getRandomColor() {
var hex = ["#96ceb4", "#ffeead", "#ff6f69", "#ffcc5c", "#88db8b0", "#528491"];
var color = hex[Math.floor(Math.random() * 6)]; // generates integer numbers [0,5], selects indexed item from hex
return color;
}
function displayShape () {
var percentages = [];
for (var i=0; i<4; i++){ // generates a list with 4 different random integer values [5,60]
percentages.push((Math.floor(Math.random() * 61) + 5));
}
var width = (Math.floor(Math.random() * 61) + 5); // generates integer numbers [5,60]
var shapeRand = Math.random()
if (shapeRand < 0.3) { // circle
style.borderRadius = "50%";
} else if (shapeRand >= 0.3 && shapeRand < 0.6) { // random shape
style.borderTopLeftRadius = percentages[0] + "%";
style.borderBottomRightRadius = percentages[1] + "%";
style.borderTopRightRadius = percentages[2] + "%";
style.borderBottomLeftRadius = percentages[3] + "%";
} else { // square
style.borderRadius = "0%";
}
//general shape styles
style.width = width + "%";
style.height = width + "%";
style.display = "block";
style.backgroundColor = getRandomColor();
style.top = percentages[0] + "%";
style.left = percentages[3] + "%";
start = new Date().getTime(); // saves time when shape is created
console.log(width);
console.log(getRandomColor());
console.log(shapeRand);
console.log(percentages);
}
function displayShapeDelay () { // calls the main function with a delay between ]0s,2s[
setTimeout(displayShape, Math.random() * 2000);
}
document.getElementById('stop').onclick = function() {
}
}
在我拥有这个之前:
我的目标是将 var 'time' 返回到全局范围,这样我就可以用它来创建一个数组,其中包含每次点击时创建的每个值。我意识到匿名函数不可能做到这一点。
document.getElementById('shape').onclick = function() { // calls the delay function
style.display = "none";
displayShapeDelay();
end = new Date().getTime();
time = (end - start)/1000 ;
document.getElementById('timeBox').innerHTML = time + 's';
return time
}
所以这是我现在的代码:
var shapeClick = document.getElementById('shape');
shapeClick.addEventListener("click", a, false);
shapeClick.addEventListener("click", b, false);
function a() {
style.display = "none";
displayShapeDelay(); // calls the delay function
}
function b() {
end = new Date().getTime(); // saves time when clicked
var time = (end - start)/1000 ; // calculates interval from shape creation until click
document.getElementById('timeBox').innerHTML = time + 's';
return time;
}
document.getElementById('testbox').innerHTML = b();
现在,这有几个问题:
1- 我似乎无法理解为什么在按下“开始”按钮后会为两个“时间 div”分配值。这意味着函数 b 正在运行,但它不应该只在 onClick 事件之后运行吗?
2- 在“第一轮”中,我理解为什么两个值都显示为 NaN,因为还没有为变量“time”分配值。但是在 onClick 事件执行后,'timeBox' 内部分配的 'time' 值可以正常工作,但在函数外部调用的则不能。函数 b 中的“返回时间”不是应该返回“时间”变量的值吗?
提前致谢!
最佳答案
粉彩之地
onclick
函数是在单击开始按钮时执行的大量代码的外部函数。此外,每次单击开始按钮时,它都会运行:快速单击多次启动以查看问题。 .
在#start.onclick() 中你有
document.getElementById('testbox').innerHTML = b();
在主线单击处理程序代码中:它不在另一个函数中,并在单击开始按钮时运行。由于 end
尚未设置,因此 time
的结果为 NaN
。 function b
中的代码也设置了#timebox 的内容。
如果您在严格模式下运行代码,javascript 引擎会告诉您end
尚未声明。它应该是 - 即使在全局范围内需要。
顺便说一句,Date.now()
避免了创建和丢弃 Date 对象的需要,相当于 new Date().getTime()
.
我建议修改代码,将 Pastel Land 的逻辑移到开始按钮点击处理程序之外,并让点击处理程序根据需要调用主应用程序代码,但只包含特定于开始操作本身的逻辑。如果你想避免污染全局范围,你可以将所有代码包含在 IIFE 中。 (立即调用的函数表达式)将服务于单击处理程序当前提供的相同范围包含规定。请注意,我认为当前状态下的代码呈现一个 x-y problem。 :-)
游戏
Pastel Land 的重组版本如下所示,原因有几个:您有时间亲自尝试,大部分代码是您的,其余代码演示了建议的含义。这是一个非常愚蠢的游戏,值得一玩!
<!DOCTYPE html>
<html>
<head>
<title>PastelLand</title>
<meta charset="utf-8">
<script>
window.addEventListener("load", function() // an IIFE
{"use strict"
// Pastel Land
var running = false;
var start = 0;
var end = 0;
var times = []; // calculating average still to do
var el, style;
function getRandomColor() {
var hex = ["#96ceb4", "#ffeead", "#ff6f69", "#ffcc5c", "#88db8b0", "#528491"];
var color = hex[Math.floor(Math.random() * 6)]; // generates integer numbers [0,5], selects indexed item from hex
return color;
}
function displayShape () {
var percentages = [];
for (var i=0; i<4; i++){ // generates a list with 4 different random integer values [5,60]
percentages.push((Math.floor(Math.random() * 61) + 5));
}
var width = (Math.floor(Math.random() * 61) + 5); // generates integer numbers [5,60]
var shapeRand = Math.random()
if (shapeRand < 0.3) { // circle
style.borderRadius = "50%";
} else if (shapeRand >= 0.3 && shapeRand < 0.6) { // random shape
style.borderTopLeftRadius = percentages[0] + "%";
style.borderBottomRightRadius = percentages[1] + "%";
style.borderTopRightRadius = percentages[2] + "%";
style.borderBottomLeftRadius = percentages[3] + "%";
} else { // square
style.borderRadius = "0%";
}
//general shape styles
style.width = width + "px";
style.height = width + "px";
style.position = "absolute"
style.display = "block";
style.backgroundColor = getRandomColor();
style.top = percentages[0] + "%";
style.left = percentages[3] + "%";
start = Date.now(); // saves time when shape is created
console.log(width);
console.log(getRandomColor());
console.log(shapeRand);
console.log(percentages);
}
function displayShapeDelay () { // calls the main function with a delay between ]0s,2s[
setTimeout(displayShape, Math.random() * 2000);
}
function readyAlert() {
document.getElementById('readyContainer').style.display = 'none';
}
function userFound() {
style.display = "none";
end = Date.now();
var time = (end - start)/1000 ; // calculates interval from shape creation until click
document.getElementById('timeBox').innerHTML = time + 's';
displayShapeDelay(); // calls the delay function
times.push( time); // saves time user took to find shape
}
function userStart() {
if( running)
return;
running = true;
document.getElementById('readyContainer').style.display = 'block';
document.getElementById('readySeconds').innerHTML = '3'
setTimeout(function() {document.getElementById('readySeconds').innerHTML = '2'}, 1000);
setTimeout(function() {document.getElementById('readySeconds').innerHTML = '1'}, 2000);
setTimeout(readyAlert,3000);
setTimeout(displayShape, 3000);
times.length = 0; // reset times array
}
function userStop() {
running = false;
style.display="none"
}
function init() {
el = document.getElementById('shape');
style = el.style;
el.addEventListener("click", userFound, false);
document.getElementById('start').onclick=userStart;
document.getElementById('stop').onclick=userStop;
}
return init; // window load listener
}());
</script>
</head>
<body>
<div id='header'> <h1> Pastel Land </h1> </div>
<div id='container'>
<div id='readyContainer'>
<h3> This game will start in </h3>
<h1 id='readySeconds'> </h1>
</div>
<div id='shape' style="height:40px;width:40px;"></div>
</div>
<div id='features'>
<button id='start'> START </button>
<button id='stop'> STOP </button>
<p id='timeBox'></p>
<p id='timeAverageBox'></p>
</div>
<div id='testbox'> </div>
</body>
</html>
平均值的计算和显示以及对页面呈现的微小更改仍有待完成(我不是在编码它们!)。宽度和高度的单位从“%”更改为“px”(像素)和“position:absolute;”添加到 shape.style。函数 a
和 b
合并为函数 userFound
。省略了涉及“testbox”的代码。 IIEF 返回一个在窗口加载后执行的初始化函数。
注意事项
userStart
和 userStop
单击事件处理程序是使用名为 function declarations 定义的而不是在调用其他函数的参数列表中将它们编码为匿名函数。
声明的函数名称指的是通过声明创建的函数对象。因此,将元素的 onclick
属性的值设置为函数名称是可行的,因为该属性需要一个函数对象值。将 onclick
设置为调用其中一个处理程序返回的未定义值将不起作用。
启动/停止处理程序可能已经注册为“点击”事件监听器,使用addEventListener
而不是元素 onclick
值。
init
函数不由 IIFE 调用。 IIFE 本身在
window.addEventListener("load", function() { // IIFE code }() );
语句在页面的头部执行。 IIFE 中在顶层声明的所有函数对象都在此时创建。 IIFE 返回的函数 init
被注册为监听器,以便在为 HTML 正文创建所有 DOM 元素并触发窗口加载事件后执行。
如果在其他el
和style
初始化后,从init
调用userStart
,游戏将开始.尽管通常调用 userStart
以响应单击开始按钮,但如果通过其他方式调用,它的行为仍然相同。
关于javascript - 函数 Javascript || 的 NaN 返回值函数执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36780257/