我正在建立一个基于浏览器的认知心理学实验,类似于游戏Simon(但没有80年代的天赋)。
有些php确定将在给定试验中显示的序列并将其传递给JS数组,在那里我遇到两种问题:(1)优雅地处理刺激显示,以及(2)分离“演讲“从”召回“阶段开始。虽然我在这里找到了一些关于这个问题的每一半的有用信息,但是根据我的知识,整合这两个任务已经提出了独特的挑战,这里没有讨论过。所以这里:
(1)使用setTimeouts一次显示数组一个元素的内容:
这部分代码是功能性的,但我无法想象它是最优的。部分并发症是时间间隔不均匀:刺激出现700ms,但它们之前,之间和之后的间隙是500ms。 (很烦人,但是我无法帮助它。)幸运的是,对于我来说,需要提供的东西绝不会超过5件,所以对这些时间戳进行硬编码至少是一个选项,如果不是一个好的话。 / p>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<style>
body
{color:black}
table
{margin: 100px auto 0 auto;
border: 1;
text-align:center;
}
td
{
width: 100px;
height:100px;
vertical-align:middle;
}
tr:focus
{ outline: none; }
</style>
</head>
<body onload="displayStimuli()">
<table>
<tr>
<td id="TopLeft">
</td>
<td id="TopMiddle">
</td>
<td id="TopRight">
</td>
</tr>
<tr>
<td id="MiddleLeft">
</td>
<td id="MiddleMiddle">
</td>
<td id="MiddleRight">
</td>
<tr>
<td id="BottomLeft">
</td>
<td id="BottomMiddle">
</td>
<td id="BottomRight">
</td>
</tr>
</tr>
</table>
</body>
<script>
var stimuli = new Array(1,2,3,4,"*");
var cells = new Array("TopLeft", "TopRight", "BottomLeft", "BottomRight", "MiddleMiddle");
var stimOn = new Array(500,1700,2900,4100, 5300) ; //this is a pretty unintelligent solution, but it works!
var stimOff = new Array(1200,2400,3600,4800, 6000);
function displayStimuli(){
for (i=0; i<stimuli.length; i++)
{
setTimeout(function (i) {return function(){
document.getElementById(cells[i]).innerHTML=stimuli[i];
};
}(i),stimOff[i]);//when display the next one
setTimeout(function (i) {return function(){
document.getElementById(cells[i-1]).innerHTML="";//There will be an error here because for the first item, i-1 is undefined. I can deal.
};
}(i),stimOn[i]);//when to remove the previous one
}
//showRecall(); //see part (2)!
}
</script>
如果有人想想出一个很好的方法来清理它,请随意!然而,我现在面临的更为棘手的挑战是下一部分。
(2)等待调用函数,直到浏览器完成显示某些先前setTimeout函数的最终结果。
在这里,我发现可能是部分解决方案的建议(例如Javascript nested loops with setTimeout),但我无法完全理解如何将它们与我当前的设计相结合。从概念上讲,这就是我想要发生的事情:
//php sends stimulus array (not including final "*") to js
//js steps through the array, displaying and removing the pictures as above
//after the browser has finished *displaying* the sitmuli in the loop, call a new js function, "recall()".
//recall(){
//this part is fairly straightforward
//}
我见过的一些答案似乎表明这可以用普通的'js',而其他人坚持认为jQuery可以解决问题。我对两种解决方案持开放态度,但是没有看到任何适用于我的情况,其中执行函数的提示不是一定的超时(因为它会因不同长度的试验而变化),也没有只是等待代码被处理,而不是检测浏览器何时完成显示的东西。
HALP?
答案 0 :(得分:1)
这只是一种建议/替代方式,但不是使用for循环并在将来进一步计算超时,您可以尝试逐步设置新的超时,如下所示:
var stimuli = new Array(1,2,3,4,"*");
var cells = new Array("TopLeft", "TopRight", "BottomLeft", "BottomRight", "MiddleMiddle");
var alreadyOn = false;
// call startUp on load instead of displayStimuli
function startUp() {
setTimeout(displayStimuli, 1200);
}
function displayStimuli(){
if(stimuli.length>0) { // if we have any stimuli left
if(alreadyOn) {
document.getElementById(cells.shift()).innerHTML="";
stimuli.shift(); // here we remove elements from the arrays
setTimeout(displayStimuli, 500); // show again in 500ms
} else {
document.getElementById(cells[0]).innerHTML=stimuli[0];
setTimeout(displayStimuli, 700); // remove in 700ms
}
alreadyOn = !alreadyOn; // flip it for the next round
} else { // no stimuli left, move on.
showRecall();
}
}
此代码将在删除最后一个激励后调用showRecall 500ms,您可以根据自己的需要进行更改,它们仅仅是语句,所以只需在那里插入自己的逻辑。