Global setTimeout #1859
-
I want to create a timer that operates across different sets of trials. I want to define it on the procedure timeline level. After starting the procedure it should choose a random time after which it changes the size and colour of certain span element, waits for 1s, and after that return parameres to default. I thought that I could achieve this with nested setTimeout but unfortunately, I've encountered some problems. In my particular case pressing a key ends up the trial and this blocks somehow the execution of setTimeout callback. Minimal valid example in the attachment. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @rMinion, the reason your The solution is just to replace your But there are a few other things I noticed, based on what I think you want to do. First, if you want the red text to be shown for the duration of Second, you were using Third, the So here's my solution (and apologies if this isn't what you're trying to do!) <!DOCTYPE html>
<html>
<head>
<script src="jspsych-6.3.0/jspsych.js"></script>
<script src="jspsych-6.3.0/plugins/jspsych-html-keyboard-response.js"></script>
<script src="jspsych-6.3.0/plugins/jspsych-instructions.js"></script>
<script src="jspsych-6.3.0/plugins/jspsych-call-function.js"></script>
<link href="jspsych-6.3.0/css/jspsych.css" rel="stylesheet">
</head>
<style id="keypress-style">
#keypress {color: red; font-size:300%;}
</style>
<body>
<script>
//Function to generate random numbers between min and max
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// change to red, and set up a timer to change to black
function red() {
// access the keypress-style element and change the CSS to red
document.getElementById('keypress-style').textContent = '#keypress {color: red; font-size:300%;}';
//setting a new random red_interval
red_interval = getRandomIntInclusive(1, 5) * 1000
console.log("red", red_interval)
// change to black after the red interval ends
red_interval_timeout = setTimeout(black, red_interval);
}
// change to black, and set up a timer to change to red
function black() {
console.log("black", black_interval)
// access the keypress-style element and change the CSS to black
document.getElementById('keypress-style').textContent = '#keypress {color: black; font-size:100%;}';
// change back to red after the black interval ends
red_interval_timeout = setTimeout(red, black_interval)
}
// Value in ms after which the span element should be coloured red
var red_interval = null
// Value in ms after which the span element should be coloured white
var black_interval = 1000
// Keypress counter
var keypress = 0
var start_first_timer = {
type: 'call-function',
func: function() {
//setting the first value of red_interval
red_interval = getRandomIntInclusive(1, 5) * 1000
// change color to red
red();
}
}
// Triall
var letter =
{
type: 'html-keyboard-response',
stimulus: ``,
prompt: "Press a",
choices: ["a"],
on_start: function (letter) {
letter.stimulus = `<span id = "keypress">${keypress}</span>`
},
on_finish: function () {
keypress++
}
}
var clear_last_timer = {
type: 'call-function',
func: function() {
clearTimeout(red_interval_timeout);
}
}
// Timeline
var procedura = {
timeline: [letter],
repetitions: 100
}
jsPsych.init({
timeline: [start_first_timer, procedura, clear_last_timer],
on_finish: function () {
jsPsych.data.displayData()
}
});
</script>
</body>
</html> |
Beta Was this translation helpful? Give feedback.
Hi @rMinion, the reason your
setTimeout
callback isn't running after a key press is because you're using thejsPsych.pluginAPI.setTimeout
function, which registers the timer in the core jsPsych code so that it can be easily cleared at the end of a trial withjsPsych.pluginAPI.clearAllTimeouts
. The html-keyboard-response plugin happens to calljsPsych.pluginAPI.clearAllTimeouts
when the trial ends, which is also clearing your global timer (line 83). Using thejsPsych.plulginAPI.setTimeout
function is generally recommended so that it can be easily cleared, because timers should almost always be cleared at the end of a trial (otherwise it will continue running during the next trial, which is…