Sei sulla pagina 1di 89

using jspsych to

conduct behavioral
research online

JOSH DE LEEUW WORKSHOP IN METHODS AT INDIANA UNIVERSITY


PART 1: OVERVIEW OF ONLINE
EXPERIMENTS & JSPSYCH
SO YOU WANT TO RUN AN ONLINE EXPERIMENT

you'll need... front end server labor

● jsPsych ● psiturk ● psiturk


● Qualtrics ● Qualtrics ● Amazon CLT
● Inquisit ● JATOS ● Prolific
● ScriptingRT … Academic
… and more …
and more and more
WHY USE JSPSYCH?

It's free and open source. It's JavaScript based, so no


special software is required for
You can go beyond the participants.
survey, and run "lab-like"
experiments. Run experiments online and in
the lab with no modifications.
WHY AVOID JSPSYCH?

If you are doing survey If your experiments don't have


research, it's easier to use a trial-based structure, it might
other options. not be worth it.

You need to program a bit.


THE
ARCHITECTURE
OF JSPSYCH
WE TEND TO REPEAT
THE SAME KINDS OF
EXPERIMENTS
GOAL: PROGRAM EXPERIMENTS IN A WAY
THAT MAXIMIZES CODE RE-USE

Reuse code for the same Make it easy to share


1 kinds of tasks, regardless of 2 innovations in experimental
the experimental context design

Be flexible so that minor Code for one task should


3 variations in procedure do
4 work seamlessly with the
not require new code code for any other task
STRUCTURE & CONTENT

structure content
Display instructions to the What the instructions say
participant
How long the image should
Show an image and be displayed
measure response time for
a keyboard response What keys the participant
is allowed to press
Display a question with a
likert scale and record the How many response
response options are on the scale
STRUCTURE & CONTENT

jspsych handles the structure,


letting you focus exclusively
on the content.
ARCHITECTURE OVERVIEW

core library plugins


Required for every jspsych Each plugin file defines a
experiment. Handles functions single task that a
that are common to all participant can do. The
experiments: controlling flow, basic building blocks of
data management, etc... an experiment.
CORE LIBRARY MODULES

jsPsych jsPsych.data jsPsych.randomization


The core module has all the Functions for interacting with Functions for generating random
internal functions necessary for data generated by the experiment. orders of items (e.g. trials, stimuli)
running an experiment, plus a few Add to, modify, retrieve, or view by shuffling, repeating, and
utilities like media preloading. different portions of the data. sampling.

jsPsych.turk jsPsych.pluginAPI
Functions for interacting with Helpful functions for developing
Mechanical Turk. plugins. Includes methods for
getting keyboard responses and
processing plugin parameters.
WHAT'S A PLUGIN?

{
… define a single, atomic unit of the experiment.

plugins … follow a strict template (which allows substantial freedom)

… provide a set of parameters to allow custom content


PLUGIN EXAMPLES

jspsych-single-stim.js
Display a stimulus on the screen and record what key the
participant presses in response and the response time.

Parameters control: what stimulus is presented, what keys can be pressed, how
long stimulus is displayed, how long participant has to respond
PLUGIN EXAMPLES

jspsych-instructions.js
Display a set of instructions to the participant

Parameters control: what the instructions say, whether the participant can go back
to previous pages to re-read, whether keys or the mouse are used to navigate
PLUGIN EXAMPLES

jspsych-visual-search-circle.js
Perform a trial in a visual search task with search array
organized in a circle around a fixation point.

Parameters control: search array size, display size, target/distractor image, fixation
image, response keys, maximum search duration, fixation duration
PLUGIN EXAMPLES

the list of plugins


http://docs.jspsych.org/plugins/overview/#list-of-available-plugins
EXPERIMENT START THE TIMELINE

EXPERIMENT END
Every experiment has a timeline
EXPERIMENT START THE TIMELINE

EXPERIMENT END
Timelines are ordered lists of trials
EXPERIMENT START THE TIMELINE

EXPERIMENT END
Timelines can be linear
EXPERIMENT START THE TIMELINE

EXPERIMENT END
REPEAT UNTIL...

or can contain loops, nested structures, ...


EXPERIMENT START THE TIMELINE

EXPERIMENT END
IF...

… or conditionals
TO CREATE AN
EXPERIMENT, SPECIFY
THE TIMELINE
FEATURES OF JSPSYCH

DATA MANAGEMENT EVENT-DRIVEN PROGRESS BAR


Data collection is automatic. FUNCTIONS
Optionally add a progress bar
Data can be output as json or Add custom, arbitrary functions to the top of an experiment
csv strings. Easy to add custom that trigger whenever a trial page without any additional
data fields. starts or ends, when new data is coding
added, or when the experiment
finishes.

RANDOMIZATION PRELOAD CONTENT MTURK SUPPORT


Randomize the order of trials Preload media content like Built-in support for tracking
by specifying a single images and audio files to ensure mechanical turk worker
parameter. Helper methods for precise timing during the variables like workerID and
shuffling orders, generating experiment. assignmentID.
randomly ordered factorial
combinations, and repeating a
set of trials in a random order.
WHAT ABOUT
RESPONSE TIMES?

3 concerns hardware
Variations in computer hardware can cause SUGGESTED READING
measurement differences of 10-100ms. Online
experiments will have variability in hardware. Brand & Bradley (2012). doi:10.1177
/0894439311415604

Crump, McDonnell, & Gureckis (2013).


software doi:10.1371/journal.pone.0057410

JavaScript response times* are a bit slower (10-40ms) de Leeuw & Motz (2015). doi:10.3758
than MATLAB Psychtoolbox, but have equivalent /s13428-015-0567-2
variance. Plant & Turner (2009). doi:10.3758/BRM.
* using the most conservative measurement strategy 41.3.598

environment Reimers & Stewart (2015). doi:10.3758


/s13428-014-0471-1
RT-based studies replicate well in online
environments (but replications are not controlled
experiments).
WHAT ABOUT
PRESENTATION TIMES?

Fixed refresh cycle


(~16.67ms)
{
SUGGESTED READING

Neath et al. (2011).


doi: 10.3758/s13428-011-0069-9

Reimers & Stewart (2015). doi:10.3758


Command issued to Command issued to /s13428-014-0471-1
display stimulus clear stimulus

Display duration is longer than requested, by about 20ms on average. The exact
length depends on the machine and browser.

Modern JavaScript techniques can improve this slightly.


DOCUMENTATION &
SUPPORT

jspsych is (mostly) well-documented


http://docs.jspsych.org

public archive of support Q&A


https://groups.google.com/forum/#!forum/jspsych
OPEN SOURCE

jspsych is hosted on GitHub


https://github.com/jodeleeuw/jsPsych

You can: view implementation of algorithms, track


changes to the code base, suggest improvements,
copy & modify the library, contribute new features
and plugins, learn from example code
PART 2: A MINIMAL INTRODUCTION TO JAVASCRIPT
VARIABLES IN JAVASCRIPT

JavaScript variables declared with the


var keyword. Variables are untyped.

var x = 123;

x = 'hello'; // no error
VARIABLES IN JAVASCRIPT

Variables can contain var f = function(){


functions return 'hello world';
}

function alertmsg(x){
message = x();
alert(message);
}
This line will show the
alertmsg(f);
message hello world.
VARIABLES IN JAVASCRIPT

Arrays are critical for using jspsych.


Create an empty array var arr = [];

Create an array with content var arr = [3,5,2,4];

Assign a value to an array item arr[0] = 5;

Add a new item to the end of an array arr.push(2);

Get the value of an array item console.log(arr[2]);


VARIABLES IN JAVASCRIPT

Objects are the building blocks of experiments


Create a new object var obj = {};

Create a new object with properties var obj = {


color: 'blue',
this is the 'key' size: 'large' this is the 'value'

};

Assign a property to an existing object obj.color = 'red';


VARIABLES IN JAVASCRIPT

Alternate method of property assignment obj['color'] = 'orange';

Object properties can be functions obj.add = function(x,y) {


return x+y
}

New properties can be added to objects at obj.weight = 125;


any point
HOW DO YOU...

Create an empty array named 'exp'?


HOW DO YOU...

Create an empty array named 'exp'? var exp = [];


HOW DO YOU...

Create an empty array named 'exp'? var exp = [];

Create an object called 'trial' with property


'type' set to 'text' and property 'text' set to
'hello!'?
HOW DO YOU...

Create an empty array named 'exp'? var exp = [];

Create an object called 'trial' with property var trial = {


'type' set to 'text' and property 'text' set to type: 'text',
'hello!'? text: 'hello!'
}
HOW DO YOU...

Create an empty array named 'exp'? var exp = [];

Create an object called 'trial' with property var trial = {


'type' set to 'text' and property 'text' set to type: 'text',
'hello!'? text: 'hello!'
}

Add the object you created to the array?


HOW DO YOU...

Create an empty array named 'exp'? var exp = [];

Create an object called 'trial' with property var trial = {


'type' set to 'text' and property 'text' set to type: 'text',
'hello!'? text: 'hello!'
}

Add the object you created to the array? exp.push(trial);


PART 3: GETTING STARTED WITH JSPSYCH
THE JAVASCRIPT DEVELOPER'S TOOLBOX

{
a programming-friendly text editor
https://atom.io

a web browser for testing


https://www.google.com/chrome
you need
to know how to open the debugging
tools in your browser of choice

a web server, eventually


HELLO, WORLD!

docs.jspsych.org/tutorials/hello-world

The hello world tutorial explains how to set up a basic experiment.


You can use it as the starting point for every experiment with jspsych.
HELLO, WORLD!

step 1: download jspsych


https://github.com/jodeleeuw/jsPsych/releases
HELLO, WORLD!

step 2: create a folder for the experiment


1) Create a folder called hello-world-experiment
2) Unzip the downloaded jspsych library, and
place the jspsych-4.2 folder in the hello-world-
experiment folder.
HELLO, WORLD!

step 3: create a new html file


Use the text editor of your choice to create a new file
called experiment.html in the hello-world-
experiment folder.
HELLO, WORLD!

step 4: insert basic HTML


nearly every HTML document has a few common elements

<!doctype html>
<html>
<head>
<title>Hello world experiment</title>
</head>
<body>
</body>
</html>
HELLO, WORLD!

step 5: import jspsych


<script> tags are used to load external JavaScript files.

<!doctype html>
<html>
<head>
<title>Hello world experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="jspsych-4.3/jspsych.js"></script>
</head>
<body>
</body>
</html>
HELLO, WORLD!

step 6: add jspsych CSS file


The CSS file provides simple visual styling

<!doctype html>
<html>
<head>
<title>Hello world experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="jspsych-4.3/jspsych.js"></script>
<link href="jspsych-4.3/css/jspsych.css" rel="stylesheet"></link>
</head>
<body>
</body>
</html>
HELLO, WORLD!

step 7: import the text plugin


Every plugin that you use must be imported

<!doctype html>
<html>
<head>
<title>Hello world experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="jspsych-4.3/jspsych.js"></script>
<script src="jspsych-4.3/plugins/jspsych-text.js"></script>
<link href="jspsych-4.3/css/jspsych.css" rel="stylesheet"></link>
</head>
<body>
</body>
</html>
HELLO, WORLD!

step 8: create a trial to print "hello, world!"


The JavaScript can be embedded directly in a <script> element

<!doctype html>
<html>
<head>
...
</head>
<body>
</body>
<script>
var hello_trial = {
type: 'text',
text: 'hello, world!'
}

jsPsych.init({
experiment_structure: [hello_trial]
});
</script>
</html>
LEXICAL DECISION TASK

Rubenstein, Garfield, & Millikan (1970)

Presented a series of individual word-like


stimuli and participants indicated whether morey
or not the word was a real English word.

High-frequency words are reacted to faster


than low-frequency words.
LEXICAL DECISION TASK

building a lexical decision task with jspsych


What tasks will participant need to do?
1) View instructions. jspsych-instructions
2) Respond to words using the keyboard. jspsych-single-stim
LEXICAL DECISION TASK

first steps: follow the hello world tutorial


1) Download jspsych
2) Create a folder to house the experiment
3) Put the jspsych library in the folder
4) Create a basic HTML document that imports the jspsych library,
jQuery, the appropriate jspsych plugins, and the jspsych CSS file.
LEXICAL DECISION TASK

the basic experiment template


You can tell jspsych to display the experiment inside a DOM element. I like to use a
<div> element to display jspsych content.
<!doctype html>
<html>
<head>
<title>Lexical Decision Task</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="jspsych-4.2/jspsych.js"></script>
<script src="jspsych-4.2/plugins/jspsych-instructions.js"></script>
<script src="jspsych-4.2/plugins/jspsych-single-stim.js"></script>
<link href="jspsych-4.2/css/jspsych.css" rel="stylesheet"></link>
</head>
<body>
<div id="jspsych-target"></div>
</body>
</html>
LEXICAL DECISION TASK
creating the word lists
<!doctype html>
<html>
<head>
<title>Lexical Decision Task</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="jspsych-4.2/jspsych.js"></script>
<script src="jspsych-4.2/plugins/jspsych-instructions.js"></script>
<script src="jspsych-4.2/plugins/jspsych-single-stim.js"></script>
<link href="jspsych-4.2/css/jspsych.css" rel="stylesheet"></link>
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>

/* experiment parameters */
var low_frequency_words = ['cove','turf','twig','foyer','denim'];
var high_frequency_words = ['chair','city','girl','food','dark'];
var nonwords = ['cowe','turv','twif','foger','dewim','thair','ciny','birl','rood','zark'];

</script>
</html>
LEXICAL DECISION TASK
adding the instructions
...
<script>

/* experiment parameters */
...

/* create the experiment timeline */


var timeline = [];

/* instructions */
var instructions = {
type: 'instructions',
pages: ['<p>You are going to see a series of individual words, some of which are ' +
'actual English words, while others are nonsense words that look like '+
'English words. Your job is to indicate whether the word is a real English '+
'word as quickly and accurately as you can.</p>'+
'<p style="font-weight:bold;">Press Y if the word is an English word.</p>'+
'<p style="font-weight:bold;">Press N if the word is not an English word.</p>'+
'<p>Click the button below to begin.</p>'],
allow_keys: false,
show_clickable_nav: true
}

timeline.push(instructions);

</script>
...
LEXICAL DECISION TASK
initialize the experiment
...
<script>

/* experiment parameters */
...

/* create the experiment timeline */


...

/* instructions */
...

/* run the experiment */


jsPsych.init({
display_element: $('#jspsych-target'),
experiment_structure: timeline
});

</script>
...
LEXICAL DECISION TASK
adding the test trials
...
/* experiment parameters */
...

var max_response_time = 2500;

/* instructions */
...

/* create test trials */

var low_frequency_trials = [];


for(var i in low_frequency_words){
low_frequency_trials.push({
type: 'single-stim',
stimuli: ['<p style="text-align:center; font-size:32px;">'+low_frequency_words[i]+'</p>'],
timing_response: max_response_time,
choices: ['y','n'],
is_html: true,
data: {word_type: 'low'}
});
}

/* run the experiment */


...
LEXICAL DECISION TASK
adding the test trials
...
/* experiment parameters */
...

/* instructions */
...

/* create test trials */


...

var high_frequency_trials = [];


for(var i in high_frequency_words){
high_frequency_trials.push({
type: 'single-stim',
stimuli: ['<p style="text-align:center; font-size:32px;">'+high_frequency_words[i]+'</p>'],
timing_response: max_response_time,
choices: ['y','n'],
is_html: true,
data: {word_type: 'high'}
});
}

/* run the experiment */


...
LEXICAL DECISION TASK
adding the test trials
...
/* experiment parameters */
...

/* instructions */
...

/* create test trials */


...

var nonword_trials = [];


for(var i in nonwords){
nonword_trials.push({
type: 'single-stim',
stimuli: ['<p style="text-align:center; font-size:32px;">'+nonwords[i]+'</p>'],
timing_response: max_response_time,
choices: ['y','n'],
is_html: true,
data: {word_type: 'nonword'}
});
}

/* run the experiment */


...
LEXICAL DECISION TASK
adding the test trials
...
/* experiment parameters */
...

/* instructions */
...

/* create test trials */


...

var all_trials = low_frequency_trials.concat(high_frequency_trials, nonword_trials);


all_trials = jsPsych.randomization.shuffle(all_trials);

timeline = timeline.concat(all_trials);

/* run the experiment */


...
LEXICAL DECISION TASK
adding the test trials
...
/* experiment parameters */
...

/* instructions */
...

/* create test trials */


...

var all_trials = low_frequency_trials.concat(high_frequency_trials, nonword_trials);


all_trials = jsPsych.randomization.shuffle(all_trials);

timeline = timeline.concat(all_trials);

/* run the experiment */


jsPsych.init({
display_element: $('#jspsych-target'),
experiment_structure: timeline,
on_finish: function() { jsPsych.data.displayData('csv'); }
});
STORING DATA

jspsych does not have built-in permanent data storage


Data is stored within the jspsych.data object, but this object only exists
on the computer running the experiment.

To store data permanently, you need to use a server-side database, write


files to a directory on the server, or use a third-party service for data
storage (psiturk, keen.io, JATOS).

Some example solutions are shown in the jspsych docs: http://docs.jspsych.


org/features/data/
STORING DATA

a few data storage options


php/file - You can use PHP to write a CSV or JSON file to your server.
http://docs.jspsych.org/features/data/#storing-data-permanently-as-a-file

php/mysql - Write the data to a database that you manage directly.


http://docs.jspsych.org/features/data/#storing-data-permanently-in-a-mysql-database

psiturk - Use psiturk to launch a server on your computer and store data
https://github.com/jodeleeuw/sample-jspsych-psiturk-experiment

jatos - Just Another Tool for Online Studies has example jspsych experiments.
https://github.com/JATOS/JATOS/wiki/Example-Studies

keen.io - A third-party service that lets you write data to their servers, without
having a server-side script to write data.
PLUGIN
DEVELOPMENT
CREATING A NEW PLUGIN

when should you create a new plugin?


The task you want to create is impossible with the current set of plugins
(usually because you need subjects to respond/interact in a novel way).

Sometimes you can use existing plugins to build an experiment, but it would
be easier to implement a plugin. For example, a visual search task could be
done with the single-stim plugin, but a custom visual search plugin made it
easier to create the experiment (and share the plugin).
CREATING A NEW PLUGIN

how do plugins work?


jsPsych.init called and Each {} on the timeline is The plugin.create method
experiment_structure passed to the corresponding returns an array of trial
is parsed plugin.create method objects

Each new trial is initialized by calling the appropriate


Experiment
plugin.trial method, with the array from plugin.create
begins
passed in as a parameter
CREATING A NEW PLUGIN

an empty plugin
jsPsych['plugin-name'] = (function(){

var plugin = {};

plugin.create = function(params){
var trials = [];

trials.push({});

return trials;
}

plugin.trial = function(display_element, trial){


jsPsych.finishTrial();
}

return plugin;

})();
CREATING A NEW PLUGIN

an empty plugin
jsPsych is an object. This adds a new property to jsPsych['plugin-name'] = (function(){
the jsPsych object with the name 'plugin-name'
var plugin = {};

plugin.create = function(params){
var trials = [];

trials.push({});

return trials;
}

plugin.trial = function(display_element, trial){


jsPsych.finishTrial();
}

return plugin;

})();
CREATING A NEW PLUGIN

an empty plugin
This strange looking syntax is actually a neat jsPsych['plugin-name'] = (function(){
feature of JavaScript that enables persistence
and state. Functionally, it ensures that plugins var plugin = {};
are encapsulated and protected from plugin.create = function(params){
interference from other code. var trials = [];

trials.push({});

return trials;
}

plugin.trial = function(display_element, trial){


jsPsych.finishTrial();
}

return plugin;

})();
CREATING A NEW PLUGIN

an empty plugin
jsPsych['plugin-name'] = (function(){

Create a new object called plugin var plugin = {};

plugin.create = function(params){
var trials = [];

trials.push({});

return trials;
}

plugin.trial = function(display_element, trial){


jsPsych.finishTrial();
}

return plugin;

})();
CREATING A NEW PLUGIN

an empty plugin
jsPsych['plugin-name'] = (function(){

var plugin = {};

Add a create property, which contains a function plugin.create = function(params){


var trials = [];
that accepts a single argument. This method
needs to return an array, with each element of trials.push({});
the array containing the trial properties.
return trials;
}

plugin.trial = function(display_element, trial){


jsPsych.finishTrial();
}

return plugin;

})();
CREATING A NEW PLUGIN

an empty plugin
jsPsych['plugin-name'] = (function(){

var plugin = {};

plugin.create = function(params){
var trials = [];

trials.push({});

Add a trial property, with a function to run the return trials;


}
trial. It should have two parameters, the first is the
DOM element that will display the jsPsych plugin.trial = function(display_element, trial){
content. The second is the array of trial properties jsPsych.finishTrial();
generated by the create method above. }

return plugin;
This method must call jsPsych.finishTrial() when it
is done running the trial. })();
CREATING A NEW PLUGIN

an empty plugin
jsPsych['plugin-name'] = (function(){

var plugin = {};

plugin.create = function(params){
var trials = [];

trials.push({});

return trials;
}

plugin.trial = function(display_element, trial){


jsPsych.finishTrial();
}

return the plugin object, which attaches it to the return plugin;


jsPsych['plugin-name'] property.
})();
CREATING A NEW PLUGIN

jsPsych['random-number'] = (function(){

var plugin = {};

plugin.create = function(params){
var trials = [];
name the plugin
return trials;
}
The convention is to name the file containing the
plugin jspsych-plugin-name.js. This plugin is plugin.trial = function(display_element, trial){
going to generate a random number and display it, jsPsych.finishTrial();
so we will call it random-number. The plugin file }
would be jspsych-random-number.js.
return plugin;

})();
CREATING A NEW PLUGIN

jsPsych['random-number'] = (function(){

var plugin = {};

plugin.create = function(params){
var trials = [];
add plugin parameters
trials.push({
number: Math.random() * params.multiplier
You can define any parameters that you want in });
the create method. You can perform computations
on the parameters passed in from the timeline if return trials;
necessary. }

plugin.trial = function(display_element, trial){


jsPsych.finishTrial();
}

return plugin;

})();
CREATING A NEW PLUGIN
jsPsych['random-number'] = (function(){

var plugin = {};

plugin.create = function(params){
...
}
display content plugin.trial = function(display_element, trial){
display_element.html(
You will probably want to show something on the '<p>The number is: ' + trial.number + '</p>'
screen. There are lots of ways to do this, including );
the append and html methods. jsPsych.finishTrial();
}

return plugin;

})();
CREATING A NEW PLUGIN
jsPsych['random-number'] = (function(){

var plugin = {};

plugin.create = function(params){
...
}
allow content to persist plugin.trial = function(display_element, trial){
display_element.html(
In order for the display to be visible for a '<p>The number is: ' + trial.number + '</p>'
perceivable amount of time, we need to delay the );
execution of the end of the trial. setTimeout is the setTimeout(function(){
go-to option in JavaScript for delayed execution. display_element.empty();
jsPsych.finishTrial();
}, 1000);
}

return plugin;

})();
CREATING A NEW PLUGIN
jsPsych['random-number'] = (function(){

var plugin = {};

plugin.create = function(params){
...
}
saving data plugin.trial = function(display_element, trial){
display_element.html(
All plugins should write data after each trial. The '<p>The number is: ' + trial.number + '</p>'
jsPsych.data.write() method will save data );
and automatically add a set of default data as well. setTimeout(function(){
display_element.empty();
jsPsych.data.write({
number: trial.number
});
jsPsych.finishTrial();
}, 1000);
}

return plugin;

})();
CREATING A NEW PLUGIN

var random_number_trial = {
using the plugin type: 'random-number',
multiplier: 15
The type argument in a trial { } will match the name }
given to the plugin. We used a single parameter jsPsych.init({
called multiplier, which we've set to be 15. experiment_structure: [random_number_trial],
on_finish: function(){jsPsych.data.displayData();}
});
ADVANCED
DESIGN
PATTERNS
ADVANCED DESIGN
PATTERNS

var words = ['dog','cat','rog','gat'];

var fixation_trial = {
type: 'single-stim',
stimuli: ['<p style='text-align:center'>+</p>'],
pattern 1: sub-trials is_html: true,
timing_response: 500,
timing_post_trial: 0,
You want to create a trial for which there is no choices: 'none'
}
plugin, but the trial could be accomplished by
combining multiple plugins in sequence. for(var i=0; i<words.length; i++){

timeline.push(fixation_trial);
You could create a new plugin, or you could use
the existing plugins to construct a new trial. timeline.push({
type: 'single-stim',
stimuli: [
A simple example: show a fixation cross before '<p style='text-align:center'>'+words[i]+'</p>'
each word in the lexical decision task. ],
timing_response: 2000,
choices: ['y','n'],
is_html: true,
});
}
ADVANCED DESIGN
PATTERNS

var response_trial = {
type: 'single-stim',
stimuli: ['Press P!'],
is_html: true,
on_finish: function(data){
pattern 2: event handlers var is_correct = (data.key_press == 80);
jsPsych.data.addDataToLastTrial({
You want to perform some action that is correct: is_correct
contingent upon what the participant did in the });
}
last trial. }

For example, you want to calculate whether their


response was correct and add the value to the
data.
ADVANCED DESIGN
PATTERNS

var show_score = {
type: 'text',
text: function(){
var alldata = jsPsych.data.getData();
var correct_responses = 0;
pattern 3: use functions as params var total_responses = 0;
for(i in alldata){
You want to set a parameter value in a trial that if(alldata[i].test == true){
depends on how the participant has responded total_responses++;
if(alldata[i].correct == true){
so far in the experiment. correct_responses++;
}
For example, you want to show the participant }
their correct response rate so far. }
var p = correct_responses / total_responses;
var percent = Math.round(p*100);
return "You have answered "+percent+"%"+
" of the questions correctly so far.";
}
};
ADVANCED DESIGN
PATTERNS

var training_trials = {
type: 'categorize',
// … other parameters here … //
}

pattern 4: loops var training_loop = {


chunk_type: 'while',
You want to repeat a set of trials until some timeline: [training_trials],
particular event happens. continue_function: function(data){
for(i in data){
if(data[i].correct == false){
For example, you want to repeat a set of training return true;
trials until the participant responds correctly. }
}
return false;
}
}
ADVANCED DESIGN
PATTERNS

var test_trial = {
type: 'single-stim',
// … other parameters here … //
}

pattern 5: conditionals var feedback_trial = {


type: 'text',
You only want to run a trial (or set of trials) if text: 'You got the last question wrong.'
some conditional statement is true. }

var feedback_chunk = {
For example, you want to display feedback on a chunk_type: 'if',
trial that doesn't have feedback support built-in timeline: [feedback_trial],
to the plugin. conditional_function: function(){
var data = jsPsych.data.getLastTrialData();
if(data.key_press == 89){
return true;
} else {
return false;
}
}
}

var timeline = [test_trial, feedback_chunk];

Potrebbero piacerti anche