📂 L10
├── 📄 index.html
├── 📄 exp.js
├── 📄 style.css
├── 📂 images
│ └── 📂 art
└── 📂 jspsych23 Lab 10: Judgment & Decision-Making
23.1 Research in Brief: The Mere Exposure Effect
23.1.1 The Research Area
Judgment and decision-making research examines how people form preferences, make choices, and evaluate information in their environment. A fundamental question in this domain concerns the origins of our preferences: Why do we like what we like? While we often believe our preferences reflect objective qualities of objects or experiences, psychological research reveals that seemingly irrelevant factors can systematically influence our evaluations.
One particularly robust finding is that familiarity itself can generate positive feelings. We tend to prefer things we have encountered before, even when we cannot consciously remember those encounters. This phenomenon has important implications for understanding consumer behavior, social relationships, and aesthetic judgments. The mere exposure effect demonstrates that repeated, unreinforced exposure to a stimulus increases liking for that stimulus, revealing how our judgments can be shaped by experiences we may not even recall.
Understanding how familiarity influences preference helps explain real-world phenomena ranging from music popularity to friendship formation. Researchers have developed controlled experimental paradigms to isolate the effects of repeated exposure from other factors that might influence liking, such as the inherent qualities of stimuli or conscious memory for previous encounters.
23.1.2 Mere Exposure Effects
The mere exposure effect (MEE) refers to the phenomenon whereby repeated, unreinforced exposure to a stimulus results in increased liking for that stimulus. First systematically investigated by Titchener in 1910 and later coined by Zajonc in 1968, this effect challenges the folk wisdom that “familiarity breeds contempt.” Instead, research consistently demonstrates that familiarity breeds liking.
The MEE occurs across diverse stimulus types including photographs, drawings, musical selections, words, nonsense syllables, and ideographs. A meta-analysis by Bornstein in 1989 found an overall effect size of r = 0.26, indicating a moderate but reliable phenomenon. The effect has been replicated in hundreds of studies across different laboratories and cultures, making it one of the most robust findings in social psychology.
Importantly, the MEE represents a form of cognitive bias because it demonstrates that our attitudes toward stimuli change not because the stimuli themselves have changed, but simply because we have been exposed to them. People are typically unaware that mere exposure has influenced their preferences, often attributing their positive feelings to inherent qualities of the stimulus rather than to their familiarity with it.
23.1.3 The Research Design
MEE studies typically use experimental designs where participants are exposed to unfamiliar stimuli at varying frequencies during a familiarization phase, followed by a rating phase where they report their liking for each stimulus. Most studies employ within-participants designs, allowing each person to rate stimuli they have seen different numbers of times.
Stimulus Presentation: Participants view a series of novel stimuli (such as unfamiliar photographs, nonsense words, or abstract images) presented multiple times. For example, one stimulus might appear once, another five times, and another ten times during the familiarization phase. Presentation is typically randomized to prevent participants from noticing the repetition pattern.
Task Requirements: After the familiarization phase, participants rate how much they like each stimulus, typically using Likert-type scales (e.g., 1 = dislike very much, 9 = like very much). Participants are usually not told that some stimuli appeared more frequently than others during the familiarization phase. The key comparison examines whether stimuli presented more frequently receive higher liking ratings than stimuli presented less frequently or not at all.
Exposure Manipulations: Researchers systematically vary several parameters including number of exposures (typically ranging from 0 to 50 presentations), exposure duration (from subliminal presentations under 5 milliseconds to several seconds), and the interval between exposures and ratings (from immediate to weeks later).
The within-participants design controls for individual differences in baseline preferences and response styles. Each participant provides ratings across all exposure frequency conditions, allowing researchers to isolate the specific effect of repetition on liking while holding constant factors like individual aesthetic preferences or mood.
23.1.4 Key Findings
Research has revealed several consistent patterns in the MEE. Liking ratings typically increase with exposure frequency up to approximately 10-20 exposures, after which the effect plateaus and may even reverse slightly, producing an “overexposure effect” where excessive repetition leads to boredom and decreased liking.
Stimulus Complexity: Complex stimuli produce stronger and more durable MEEs than simple stimuli. Complex stimuli show more rapid increases in liking at lower exposure frequencies and are less susceptible to the overexposure effect. Simple stimuli become boring more quickly, leading to decreased liking at higher exposure frequencies.
Subliminal Exposure: One of the most striking findings is that stimuli presented subliminally (too briefly for conscious recognition) produce stronger MEEs than clearly recognized stimuli. Meta-analytic data show that unrecognized stimuli yield an effect size of r = 0.53, briefly presented recognized stimuli yield r = 0.34, and fully recognized stimuli yield only r = 0.12. This inverse relationship between awareness and effect size suggests that conscious recognition actually inhibits the MEE, possibly because people discount their positive feelings when they attribute them to repeated exposure rather than to stimulus quality.
Temporal Factors: The MEE strengthens with increasing delay between exposure and rating phases. Effects can persist for at least one to two weeks. Additionally, heterogeneous (randomized) exposure sequences produce significantly stronger effects than homogeneous (massed) sequences, with heterogeneous exposures yielding r = 0.30 compared to r = -0.02 for massed exposures.
23.1.5 Implications
The distinct patterns observed in MEE research provide important insights into the relationship between familiarity and preference. The finding that subliminal exposures produce the strongest effects challenges assumptions about conscious awareness being necessary for attitude formation. This suggests that affective responses can develop through automatic, non-conscious processes.
The robustness of the MEE across stimulus types and its persistence over time indicate that this represents a fundamental property of human cognition rather than a laboratory artifact. The phenomenon has clear evolutionary significance: organisms that develop positive associations with familiar, non-threatening stimuli in their environment may gain adaptive advantages in resource allocation and threat assessment.
The MEE has practical applications in multiple domains. In marketing and advertising, the principle explains why repeated exposure to brand names and products increases consumer preference, even without explicit persuasive messaging. In social psychology, the effect helps explain proximity-based friendship formation and the development of interpersonal attraction. In aesthetics, it accounts for how initially unfamiliar art forms or musical styles become more appealing with repeated exposure.
However, the MEE also represents a genuine cognitive illusion. People typically attribute their increased liking to inherent properties of the stimulus rather than to their familiarity with it. This misattribution can lead to biased judgments in contexts ranging from personnel selection (favoring familiar candidates) to judicial decisions (being influenced by repeated exposure to certain arguments or evidence).
The phenomenon demonstrates how our subjective experiences of preference are constructed through processes we cannot directly access. Even when people are explicitly warned about the mere exposure effect, they continue to show the bias, suggesting that conscious awareness of the mechanism does not eliminate its influence. This illustrates the powerful role of automatic, implicit processes in shaping our evaluations and preferences.
23.1.6 Further Reading
Bornstein, R. F. (1989). Exposure and affect: Overview and meta-analysis of research, 1968-1987. Psychological Bulletin, 106, 265-289.
Moreland, R. L., & Topolinski, S. (2010). The mere exposure phenomenon: A lingering melody by Robert Zajonc. Emotion Review, 2, 329-339.
Roediger, H.L., Gallo, D.A. (2016). Mere Exposure Effect. In Rudiger F. Pohl (Eds.), Cognitive Illusions (2nd ed.). Routledge.
Zajonc, R. B. (1968). Attitudinal effects of mere exposure. Journal of Personality and Social Psychology Monographs, 9(2, Part 2), 1-27.
Zajonc, R. B. (2001). Mere exposure: A gateway to the subliminal. Current Directions in Psychological Science, 10, 224-228.
23.2 Program a Between-Subjects Mere Exposure Paradigm
In this lab, you’ll program a novel variation of the mere exposure paradigm. Participants will complete two phases:
- Exposure phase: View abstract paintings and examine each carefully
- Evaluation phase: Rate how much they like each image
Participants will view each painting 0, 1, 2, 5, 8, or 10 times during exposure, allowing us to test the mere exposure effect (increased liking with repeated exposure).
We also include a novel between-subjects manipulation. Participants will be told either the paintings were created by professional abstract artists or they will be told that the images were generated by AI. In reality, all paintings are AI-generated.
Research question: Does the mere exposure effect depend on beliefs about artwork origin? Will repeated exposure increase liking more for paintings believed to be human-created, or will the effect be equivalent regardless of purported source?
Your lab folder contains boilerplate files and 12 AI-generated abstract artworks:
23.2.1 Initiate JsPsych
Let’s begin by initializing jsPsych with the basic setup we typically need. In the HTML index page, all necessary files have been added: the jsPsych core files, our exp.js file, our style.css file, and the plugins required for this experiment.
I’ve also added a welcome screen and our save data trial at the end.
<!DOCTYPE html>
<html>
<head>
<title>Lab 10: Judgment & Decision-Making</title>
<!-- jsPsych -->
<script src="jspsych/jspsych.js"></script>
<link href="jspsych/jspsych.css" rel="stylesheet" type="text/css" />
<!-- jPsych plugins -->
<script src="jspsych/plugin-instructions.js"></script>
<script src="jspsych/plugin-preload.js"></script>
<script src="jspsych/plugin-html-keyboard-response.js"></script>
<script src="jspsych/plugin-image-keyboard-response.js"></script>
<script src="jspsych/plugin-image-slider-response.js"></script>
<!-- custom CSS -->
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- custom JS -->
<script src="exp.js"></script>
</body>
</html>
// ============================================
// Initiate jsPsych
// ============================================
const jsPsych = initJsPsych();
// ============================================
// Welcome
// ============================================
let welcome = {
type: jsPsychHtmlKeyboardResponse,
stimulus: "Welcome to the experiment! Press the space bar to begin.",
choices: " "
}
// ============================================
// Savd Data Trial
// ============================================
const saveData = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<div style="text-align: center;">
<p>Experiment complete!</p>
<p>Click the button below to save your data locally:</p>
<button id="save-btn" style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
Click here to save the data locally
</button>
</div>
`,
choices: "NO_KEYS",
trial_duration: null,
on_load: function() {
document.getElementById("save-btn").addEventListener("click", function() {
jsPsych.data.get().localSave("csv", "mereExposure_data.csv");
});
},
data: {
phase: "save data trial"
}
};
// ============================================
// Run jsPsych
// ============================================
jsPsych.run([
welcome,
saveData
]); 23.2.2 Add Preload
Since we’re going to need all 12 images, we can setup our preload with all 12 images.
<!DOCTYPE html>
<html>
<head>
<title>Lab 10: Judgment & Decision-Making</title>
<!-- jsPsych -->
<script src="jspsych/jspsych.js"></script>
<link href="jspsych/jspsych.css" rel="stylesheet" type="text/css" />
<!-- jPsych plugins -->
<script src="jspsych/plugin-instructions.js"></script>
<script src="jspsych/plugin-preload.js"></script>
<script src="jspsych/plugin-html-keyboard-response.js"></script>
<script src="jspsych/plugin-image-keyboard-response.js"></script>
<script src="jspsych/plugin-image-slider-response.js"></script>
<!-- custom CSS -->
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- custom JS -->
<script src="exp.js"></script>
</body>
</html>
// ============================================
// Initiate jsPsych
// ============================================
const jsPsych = initJsPsych();
// ============================================
// Preload Images
// ============================================
let preload = {
type: jsPsychPreload,
images: [
"images/art/art_1.png",
"images/art/art_2.png",
"images/art/art_3.png",
"images/art/art_4.png",
"images/art/art_5.png",
"images/art/art_6.png",
"images/art/art_7.png",
"images/art/art_8.png",
"images/art/art_9.png",
"images/art/art_10.png",
"images/art/art_11.png",
"images/art/art_12.png"],
show_progress_bar: true,
continue_after_error: false
}
// ============================================
// Welcome
// ============================================
let welcome = {
type: jsPsychHtmlKeyboardResponse,
stimulus: "Welcome to the experiment! Press the space bar to begin.",
choices: " "
}
// ============================================
// Savd Data Trial
// ============================================
const saveData = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<div style="text-align: center;">
<p>Experiment complete!</p>
<p>Click the button below to save your data locally:</p>
<button id="save-btn" style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
Click here to save the data locally
</button>
</div>
`,
choices: "NO_KEYS",
trial_duration: null,
on_load: function() {
document.getElementById("save-btn").addEventListener("click", function() {
jsPsych.data.get().localSave("csv", "mereExposure_data.csv");
});
},
data: {
phase: "save data trial"
}
};
// ============================================
// Run jsPsych
// ============================================
jsPsych.run([
welcome,
preload,
saveData
]); 23.2.3 Add Exposure Phase
We’ll add the ‘exposure’ phase, which, for now, will just display each image once.
<!DOCTYPE html>
<html>
<head>
<title>Lab 10: Judgment & Decision-Making</title>
<!-- jsPsych -->
<script src="jspsych/jspsych.js"></script>
<link href="jspsych/jspsych.css" rel="stylesheet" type="text/css" />
<!-- jPsych plugins -->
<script src="jspsych/plugin-instructions.js"></script>
<script src="jspsych/plugin-preload.js"></script>
<script src="jspsych/plugin-html-keyboard-response.js"></script>
<script src="jspsych/plugin-image-keyboard-response.js"></script>
<script src="jspsych/plugin-image-slider-response.js"></script>
<!-- custom CSS -->
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- custom JS -->
<script src="exp.js"></script>
</body>
</html>
// ============================================
// Initiate jsPsych
// ============================================
const jsPsych = initJsPsych();
// ============================================
// Preload Images
// ============================================
let preload = {
type: jsPsychPreload,
images: [
"images/art/art_1.png",
"images/art/art_2.png",
"images/art/art_3.png",
"images/art/art_4.png",
"images/art/art_5.png",
"images/art/art_6.png",
"images/art/art_7.png",
"images/art/art_8.png",
"images/art/art_9.png",
"images/art/art_10.png",
"images/art/art_11.png",
"images/art/art_12.png"],
show_progress_bar: true,
continue_after_error: false
}
// ============================================
// Welcome
// ============================================
let welcome = {
type: jsPsychHtmlKeyboardResponse,
stimulus: "Welcome to the experiment! Press the space bar to begin.",
choices: " "
}
// ============================================
// Exposure Phase
// ============================================
let exposure = {
timeline: [
{
type:jsPsychImageKeyboardResponse,
stimulus: jsPsych.timelineVariable("image"),
choices: "NO_KEYS",
stimulus_width: 250,
trial_duration: 1000,
post_trial_gap: 200
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
]
}
// ============================================
// Savd Data Trial
// ============================================
const saveData = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<div style="text-align: center;">
<p>Experiment complete!</p>
<p>Click the button below to save your data locally:</p>
<button id="save-btn" style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
Click here to save the data locally
</button>
</div>
`,
choices: "NO_KEYS",
trial_duration: null,
on_load: function() {
document.getElementById("save-btn").addEventListener("click", function() {
jsPsych.data.get().localSave("csv", "mereExposure_data.csv");
});
},
data: {
phase: "save data trial"
}
};
// ============================================
// Run jsPsych
// ============================================
jsPsych.run([
welcome,
preload,
exposure,
saveData
]);
23.2.4 Add Evaluation Phase
In the evaluation phase, participants will rate how much they like each painting using a slider. We’re using the slider response plugin, which you can read more about here: https://www.jspsych.org/latest/plugins/image-slider-response/.
We’re using the same full list of images, presented in a random order.
<!DOCTYPE html>
<html>
<head>
<title>Lab 10: Judgment & Decision-Making</title>
<!-- jsPsych -->
<script src="jspsych/jspsych.js"></script>
<link href="jspsych/jspsych.css" rel="stylesheet" type="text/css" />
<!-- jPsych plugins -->
<script src="jspsych/plugin-instructions.js"></script>
<script src="jspsych/plugin-preload.js"></script>
<script src="jspsych/plugin-html-keyboard-response.js"></script>
<script src="jspsych/plugin-image-keyboard-response.js"></script>
<script src="jspsych/plugin-image-slider-response.js"></script>
<!-- custom CSS -->
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- custom JS -->
<script src="exp.js"></script>
</body>
</html>
// ============================================
// Initiate jsPsych
// ============================================
const jsPsych = initJsPsych();
// ============================================
// Preload Images
// ============================================
let preload = {
type: jsPsychPreload,
images: [
"images/art/art_1.png",
"images/art/art_2.png",
"images/art/art_3.png",
"images/art/art_4.png",
"images/art/art_5.png",
"images/art/art_6.png",
"images/art/art_7.png",
"images/art/art_8.png",
"images/art/art_9.png",
"images/art/art_10.png",
"images/art/art_11.png",
"images/art/art_12.png"],
show_progress_bar: true,
continue_after_error: false
}
// ============================================
// Welcome
// ============================================
let welcome = {
type: jsPsychHtmlKeyboardResponse,
stimulus: "Welcome to the experiment! Press the space bar to begin.",
choices: " "
}
// ============================================
// Exposure Phase
// ============================================
let exposure = {
timeline: [
{
type:jsPsychImageKeyboardResponse,
stimulus: jsPsych.timelineVariable("image"),
choices: "NO_KEYS",
stimulus_width: 250,
trial_duration: 1000,
post_trial_gap: 200
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
]
}
// ============================================
// Evaluation Phase
// ============================================
let evaluation = {
timeline: [
{
type: jsPsychImageSliderResponse,
stimulus: jsPsych.timelineVariable("image"),
prompt: "<p>How much do you like this painting?</p>",
labels: ["Dislike Very Much", "Like Very Much"],
min: 1,
max: 9,
step: 1,
stimulus_width: 250,
slider_start: 5,
require_movement: true,
post_trial_gap: 200,
data: {
phase: "evaluation"
}
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
],
randomized_order: true
}
// ============================================
// Savd Data Trial
// ============================================
const saveData = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<div style="text-align: center;">
<p>Experiment complete!</p>
<p>Click the button below to save your data locally:</p>
<button id="save-btn" style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
Click here to save the data locally
</button>
</div>
`,
choices: "NO_KEYS",
trial_duration: null,
on_load: function() {
document.getElementById("save-btn").addEventListener("click", function() {
jsPsych.data.get().localSave("csv", "mereExposure_data.csv");
});
},
data: {
phase: "save data trial"
}
};
// ============================================
// Run jsPsych
// ============================================
jsPsych.run([
welcome,
preload,
exposure,
evaluation,
saveData
]);
23.2.5 Randomize Image Order with Unequal Repetitions
Currently, each image displays once during the exposure phase. We need to modify this so images appear 0, 1, 2, 5, 8, or 10 times.
We want to randomly pair each image with a frequency, then randomize the entire exposure block order, repeating each image that many times.
We’ll use a custom sampling function to accomplish this. Here it is in full, but we’ll walkthrough it step-by-step after:
<!DOCTYPE html>
<html>
<head>
<title>Lab 10: Judgment & Decision-Making</title>
<!-- jsPsych -->
<script src="jspsych/jspsych.js"></script>
<link href="jspsych/jspsych.css" rel="stylesheet" type="text/css" />
<!-- jPsych plugins -->
<script src="jspsych/plugin-instructions.js"></script>
<script src="jspsych/plugin-preload.js"></script>
<script src="jspsych/plugin-html-keyboard-response.js"></script>
<script src="jspsych/plugin-image-keyboard-response.js"></script>
<script src="jspsych/plugin-image-slider-response.js"></script>
<!-- custom CSS -->
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- custom JS -->
<script src="exp.js"></script>
</body>
</html>
// ============================================
// Initiate jsPsych
// ============================================
const jsPsych = initJsPsych();
// ============================================
// Preload Images
// ============================================
let preload = {
type: jsPsychPreload,
images: [
"images/art/art_1.png",
"images/art/art_2.png",
"images/art/art_3.png",
"images/art/art_4.png",
"images/art/art_5.png",
"images/art/art_6.png",
"images/art/art_7.png",
"images/art/art_8.png",
"images/art/art_9.png",
"images/art/art_10.png",
"images/art/art_11.png",
"images/art/art_12.png"],
show_progress_bar: true,
continue_after_error: false
}
// ============================================
// Welcome
// ============================================
let welcome = {
type: jsPsychHtmlKeyboardResponse,
stimulus: "Welcome to the experiment! Press the space bar to begin.",
choices: " "
}
// ============================================
// Exposure Phase
// ============================================
let exposure = {
timeline: [
{
type:jsPsychImageKeyboardResponse,
stimulus: jsPsych.timelineVariable("image"),
choices: "NO_KEYS",
stimulus_width: 250,
trial_duration: 1000,
post_trial_gap: 200
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
],
sample: {
type: "custom",
fn: function(indices){
let output = []
// Define how many times each image should appear
// shuffle so that it randomly paired with an image index
const repetitions = jsPsych.randomization.shuffle([0, 1, 2, 5, 8, 10, 0, 1, 2, 5, 8, 10])
// Add each image the specified number of times
// Loop through the repetitions array
for (let i = 0; i < repetitions.length; i++) {
const imageIndex = indices[i]
const repeatCount = repetitions[i]
// Add this image repeatCount times to output
for (let j = 0; j < repeatCount; j++) {
output.push(imageIndex)
}
}
// save the repetition data as a global property
jsPsych.data.addProperties({image_repetition_map: repetitions})
// Shuffle so the repeated images appear in random order
output = jsPsych.randomization.shuffle(output)
console.log(output)
return output
}
}
}
// ============================================
// Evaluation Phase
// ============================================
let evaluation = {
timeline: [
{
type: jsPsychImageSliderResponse,
stimulus: jsPsych.timelineVariable("image"),
prompt: "<p>How much do you like this painting?</p>",
labels: ["Dislike Very Much", "Like Very Much"],
min: 1,
max: 9,
step: 1,
stimulus_width: 250,
slider_start: 5,
require_movement: true,
post_trial_gap: 200,
data: {
phase: "evaluation"
}
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
],
randomized_order: true
}
// ============================================
// Savd Data Trial
// ============================================
const saveData = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<div style="text-align: center;">
<p>Experiment complete!</p>
<p>Click the button below to save your data locally:</p>
<button id="save-btn" style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
Click here to save the data locally
</button>
</div>
`,
choices: "NO_KEYS",
trial_duration: null,
on_load: function() {
document.getElementById("save-btn").addEventListener("click", function() {
jsPsych.data.get().localSave("csv", "mereExposure_data.csv");
});
},
data: {
phase: "save data trial"
}
};
// ============================================
// Run jsPsych
// ============================================
jsPsych.run([
welcome,
preload,
exposure,
evaluation,
saveData
]);
Let’s walk through what I did in this code and why:
This function controls how many times each image appears in your experiment. Instead of showing each image once, some images will be repeated more frequently than others.
1. Create an empty output array
This will hold all the trial indices we want to present (including repetitions).
2. Randomize repetition assignments
I want to pair each timeline_variable with a frequency.
Remember that the indices variable contains an array of numbers [0,1,2 ... 11] referring to the list of timeline variables. In this case, idices[0] is 0. If we look at the 0 index of timeline_variables we can see that it is art_1.jpg.
indices[0] == 0 == timeline_variables[0] == "images/art/art_1.png"indices[1] == 1 == timeline_variables[1] == "images/art/art_2.png"indices[2] == 2 == timeline_variables[2] == "images/art/art_4.png"- etc.
Instead of randomizing indices, however, I’m going to create a list of 12 frequencies, then randomize that list to pair it with the indices array items.
- We have 12 images total (based on your indices array)
- Each image will be randomly assigned one of these repetition counts (i.e., image 1 might get assigned 0, 1, 2, 5, 8, or 10)
- The array contains: 0, 1, 2, 5, 8, 10 (twice each)
- By shuffling, we ensure random pairing between images and repetition counts
- Example result: [5, 0, 10, 1, 8, 2, 0, 5, 1, 10, 2, 8]. This would get paired with the image indices [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] which means the first image at index 0 (art_1.jpg) will get displayed 5 times. The image at index 1 (art_2.jpg) will get displayed 0 times (none), etc.
3. Build the trial list with repetitions
Now, we need to build an array that actually repeats the indices the number of times in frequency. That is we want it result in something like [8,9,9,6,6,6,6,6,2,2,2,2,2,2,2,2, ...].
I create two loops to accomplish this. An outer loop that goes the the repetitions array, and an inner loop that adds the indices X number of times to the output array.
For example, if repetitions[0] == 5 after the shuffle. Then on the first loop it will take indices[0], which is 0 and put it 5 times in the output array so that output == [0,0,0,0,0] after the outer loop. We know that index 0 refers to art_1.jpg, so no we know that this image will be displayed five times.
for (let i = 0; i < repetitions.length; i++) {
const imageIndex = indices[i]
const repeatCount = repetitions[i]
for (let j = 0; j < repeatCount; j++) {
output.push(imageIndex)
}
}- Loop through each image (using i as the counter)
- imageIndex = which image we’re working with (e.g., image 0, 1, 2…)
- repeatCount = how many times to show this image (from our shuffled repetitions array)
- Inner loop adds that image to output the specified number of times
- Example: If image 3 has repeatCount = 5, it gets added 5 times
4. Save repetition information to data
- Records which repetition count was assigned to each image position
- This gets saved as a column in your output data
- Helps you verify your manipulation during analysis
5. Randomize trial order & return the trial order
Finally, we shuffle the new list of indices and return it from the function.
The result this will be an array of 52 numbers, referring to our timeline variables, with some repeating more often than others.
23.2.6 Add Between-Subjects Instructions
Create two instruction sets for different participant groups:
- Group 1: Told artwork was created by AI
- Group 2: Told artwork was created by human artists
We’ll create both instruction sets first, then add randomized assignment. We’ll need instruction sets for both the exposure and evaluation phases.
For now, the AI instructions are in jsPsych.run. You can swap them with the human instructions to preview the alternative version.
<!DOCTYPE html>
<html>
<head>
<title>Lab 10: Judgment & Decision-Making</title>
<!-- jsPsych -->
<script src="jspsych/jspsych.js"></script>
<link href="jspsych/jspsych.css" rel="stylesheet" type="text/css" />
<!-- jPsych plugins -->
<script src="jspsych/plugin-instructions.js"></script>
<script src="jspsych/plugin-preload.js"></script>
<script src="jspsych/plugin-html-keyboard-response.js"></script>
<script src="jspsych/plugin-image-keyboard-response.js"></script>
<script src="jspsych/plugin-image-slider-response.js"></script>
<!-- custom CSS -->
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- custom JS -->
<script src="exp.js"></script>
</body>
</html>
// ============================================
// Initiate jsPsych
// ============================================
const jsPsych = initJsPsych();
// ============================================
// Preload Images
// ============================================
let preload = {
type: jsPsychPreload,
images: [
"images/art/art_1.png",
"images/art/art_2.png",
"images/art/art_3.png",
"images/art/art_4.png",
"images/art/art_5.png",
"images/art/art_6.png",
"images/art/art_7.png",
"images/art/art_8.png",
"images/art/art_9.png",
"images/art/art_10.png",
"images/art/art_11.png",
"images/art/art_12.png"],
show_progress_bar: true,
continue_after_error: false
}
// ============================================
// Welcome
// ============================================
let welcome = {
type: jsPsychHtmlKeyboardResponse,
stimulus: "Welcome to the experiment! Press the space bar to begin.",
choices: " "
}
// ============================================
// Exposure Phase
// ============================================
let ai_exposure_instructions = {
type: jsPsychInstructions,
pages: [
`<div class="instructionStyle">
<p>This is a study of people's responses to visual stimuli. You will be presented with a series of abstract paintings one at a time, and you should examine each painting as it's presented.</p>
</div>`,
`<div class="instructionStyle">
<p>All of these paintings were generated by artificial intelligence. We're providing this information because research suggests that knowing the source of artwork may influence how people perceive it.</p>
</div>`,
`<div class="instructionStyle">
<p>After all the paintings have been presented, We'll ask you some questions about your reactions to the stimuli. There are about 50 stimuli in all, and this part of the experiment will take about 4 minutes.</p>
</div>`,
],
show_clickable_nav: true,
show_page_number: true,
data: {
phase: "instructions"
}
}
let human_exposure_instructions = {
type: jsPsychInstructions,
pages: [
`<div class="instructionStyle">
<p>This is a study of people's responses to visual stimuli. You will be presented with a series of abstract paintings one at a time, and you should examine each painting as it's presented.</p>
</div>`,
`<div class="instructionStyle">
<p>All of these paintings were created by professional abstract artists. We're providing this information because research suggests that knowing the source of artwork may influence how people perceive it.</p>
</div>`,
`<div class="instructionStyle">
<p>After all the paintings have been presented, We'll ask you some questions about your reactions to the stimuli. There are about 50 stimuli in all, and this part of the experiment will take about 4 minutes.</p>
</div>`,
],
show_clickable_nav: true,
show_page_number: true,
data: {
phase: "instructions"
}
}
let exposure = {
timeline: [
{
type:jsPsychImageKeyboardResponse,
stimulus: jsPsych.timelineVariable("image"),
choices: "NO_KEYS",
stimulus_width: 250,
trial_duration: 1000,
post_trial_gap: 200
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
],
sample: {
type: "custom",
fn: function(indices){
let output = []
// Define how many times each image should appear
// shuffle so that it randomly paired with an image index
const repetitions = jsPsych.randomization.shuffle([0, 1, 2, 5, 8, 10, 0, 1, 2, 5, 8, 10])
// Add each image the specified number of times
for (let i = 0; i < repetitions.length; i++) {
const imageIndex = indices[i]
const repeatCount = repetitions[i]
// Add this image repeatCount times to output
for (let j = 0; j < repeatCount; j++) {
output.push(imageIndex)
}
}
// save the repetition data as a global property
jsPsych.data.addProperties({image_repetition_map: repetitions})
// Shuffle so the repeated images appear in random order
output = jsPsych.randomization.shuffle(output)
return output
}
}
}
// ============================================
// Evaluation Phase
// ============================================
let ai_evaluation_instructions = {
type: jsPsychInstructions,
pages: [
`<div class="instructionStyle">
<p>You will now see a series of AI-generated abstract paintings, some of which you may have seen before and some that are new.</p>
</div>`,
`<div class="instructionStyle">
<p>For each AI-generated painting, please rate how much you like it using the scale provided. There are no right or wrong answers. We're interested in your personal preferences.</p>
</div>`,
`<div class="instructionStyle">
<p>Please respond based on your immediate impression of each painting. This part of the experiment will take about 3 minutes.</p>
</div>`,
],
show_clickable_nav: true,
show_page_number: true,
data: {
phase: "evaluation_instructions"
}
}
let human_evaluation_instructions = {
type: jsPsychInstructions,
pages: [
`<div class="instructionStyle">
<p>You will now see a series of abstract paintings created by professional artists, some of which you may have seen before and some that are new.</p>
</div>`,
`<div class="instructionStyle">
<p>For each artist-created painting, please rate how much you like it using the scale provided. There are no right or wrong answers. We're interested in your personal preferences.</p>
</div>`,
`<div class="instructionStyle">
<p>Please respond based on your immediate impression of each painting. This part of the experiment will take about 3 minutes.</p>
</div>`,
],
show_clickable_nav: true,
show_page_number: true,
data: {
phase: "evaluation_instructions"
}
}
let evaluation = {
timeline: [
{
type: jsPsychImageSliderResponse,
stimulus: jsPsych.timelineVariable("image"),
prompt: "<p>How much do you like this painting?</p>",
labels: ["Dislike Very Much", "Like Very Much"],
min: 1,
max: 9,
step: 1,
stimulus_width: 250,
slider_start: 5,
require_movement: true,
post_trial_gap: 200,
data: {
phase: "evaluation"
}
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
],
randomized_order: true
}
// ============================================
// Savd Data Trial
// ============================================
const saveData = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<div style="text-align: center;">
<p>Experiment complete!</p>
<p>Click the button below to save your data locally:</p>
<button id="save-btn" style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
Click here to save the data locally
</button>
</div>
`,
choices: "NO_KEYS",
trial_duration: null,
on_load: function() {
document.getElementById("save-btn").addEventListener("click", function() {
jsPsych.data.get().localSave("csv", "mereExposure_data.csv");
});
},
data: {
phase: "save data trial"
}
};
// ============================================
// Run jsPsych
// ============================================
// run with ai instructions
jsPsych.run([
welcome,
preload,
ai_exposure_instructions,
exposure,
ai_evaluation_instructions,
evaluation,
saveData
]);
23.2.7 Add Between-Subjects Assignment
Assign participants to conditions based on a numeric ID from the study URL. To test this code, modify your URL by adding ?id=1 or ?id=2:
file:///C:/Users/umbroson/L10/index.html?id=1
file:///C:/Users/umbroson/L10/index.html?id=2
Use odd IDs for one condition and even IDs for the other. If no ID is provided in the URL, the code will randomly assign a condition. Refresh the page to see the assignment change.
In our code, we’ve added if-else logic to change which jsPsych.run function we call.
<!DOCTYPE html>
<html>
<head>
<title>Lab 10: Judgment & Decision-Making</title>
<!-- jsPsych -->
<script src="jspsych/jspsych.js"></script>
<link href="jspsych/jspsych.css" rel="stylesheet" type="text/css" />
<!-- jPsych plugins -->
<script src="jspsych/plugin-instructions.js"></script>
<script src="jspsych/plugin-preload.js"></script>
<script src="jspsych/plugin-html-keyboard-response.js"></script>
<script src="jspsych/plugin-image-keyboard-response.js"></script>
<script src="jspsych/plugin-image-slider-response.js"></script>
<!-- custom CSS -->
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- custom JS -->
<script src="exp.js"></script>
</body>
</html>
// ============================================
// Initiate jsPsych
// ============================================
const jsPsych = initJsPsych();
// ============================================
// Between-Subjects Condition Assignment
// ============================================
// Get participant ID from URL, or generate random one if not found
let participant_id = jsPsych.data.getURLVariable("id") || jsPsych.randomization.randomInt(1, 100000);
// Assign to one of three conditions based on ID
let conditions = ["ai", "human"];
let assigned_condition = conditions[participant_id % 2];
// Save id and assignment to data
jsPsych.data.addProperties({
participant_id: participant_id,
assigned_condition: assigned_condition
});
// ============================================
// Preload Images
// ============================================
let preload = {
type: jsPsychPreload,
images: [
"images/art/art_1.png",
"images/art/art_2.png",
"images/art/art_3.png",
"images/art/art_4.png",
"images/art/art_5.png",
"images/art/art_6.png",
"images/art/art_7.png",
"images/art/art_8.png",
"images/art/art_9.png",
"images/art/art_10.png",
"images/art/art_11.png",
"images/art/art_12.png"],
show_progress_bar: true,
continue_after_error: false
}
// ============================================
// Welcome
// ============================================
let welcome = {
type: jsPsychHtmlKeyboardResponse,
stimulus: "Welcome to the experiment! Press the space bar to begin.",
choices: " "
}
// ============================================
// Exposure Phase
// ============================================
let ai_exposure_instructions = {
type: jsPsychInstructions,
pages: [
`<div class="instructionStyle">
<p>This is a study of people's responses to visual stimuli. You will be presented with a series of abstract paintings one at a time, and you should examine each painting as it's presented.</p>
</div>`,
`<div class="instructionStyle">
<p>All of these paintings were generated by artificial intelligence. We're providing this information because research suggests that knowing the source of artwork may influence how people perceive it.</p>
</div>`,
`<div class="instructionStyle">
<p>After all the paintings have been presented, We'll ask you some questions about your reactions to the stimuli. There are about 50 stimuli in all, and this part of the experiment will take about 4 minutes.</p>
</div>`,
],
show_clickable_nav: true,
show_page_number: true,
data: {
phase: "instructions"
}
}
let human_exposure_instructions = {
type: jsPsychInstructions,
pages: [
`<div class="instructionStyle">
<p>This is a study of people's responses to visual stimuli. You will be presented with a series of abstract paintings one at a time, and you should examine each painting as it's presented.</p>
</div>`,
`<div class="instructionStyle">
<p>All of these paintings were created by professional abstract artists. We're providing this information because research suggests that knowing the source of artwork may influence how people perceive it.</p>
</div>`,
`<div class="instructionStyle">
<p>After all the paintings have been presented, We'll ask you some questions about your reactions to the stimuli. There are about 50 stimuli in all, and this part of the experiment will take about 4 minutes.</p>
</div>`,
],
show_clickable_nav: true,
show_page_number: true,
data: {
phase: "instructions"
}
}
let exposure = {
timeline: [
{
type:jsPsychImageKeyboardResponse,
stimulus: jsPsych.timelineVariable("image"),
choices: "NO_KEYS",
stimulus_width: 250,
trial_duration: 1000,
post_trial_gap: 200
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
],
sample: {
type: "custom",
fn: function(indices){
let output = []
// Define how many times each image should appear
// shuffle so that it randomly paired with an image index
const repetitions = jsPsych.randomization.shuffle([0, 1, 2, 5, 8, 10, 0, 1, 2, 5, 8, 10])
// Add each image the specified number of times
for (let i = 0; i < repetitions.length; i++) {
const imageIndex = indices[i]
const repeatCount = repetitions[i]
// Add this image repeatCount times to output
for (let j = 0; j < repeatCount; j++) {
output.push(imageIndex)
}
}
// save the repetition data as a global property
jsPsych.data.addProperties({image_repetition_map: repetitions})
// Shuffle so the repeated images appear in random order
output = jsPsych.randomization.shuffle(output)
return output
}
}
}
// ============================================
// Evaluation Phase
// ============================================
let ai_evaluation_instructions = {
type: jsPsychInstructions,
pages: [
`<div class="instructionStyle">
<p>You will now see a series of AI-generated abstract paintings, some of which you may have seen before and some that are new.</p>
</div>`,
`<div class="instructionStyle">
<p>For each AI-generated painting, please rate how much you like it using the scale provided. There are no right or wrong answers. We're interested in your personal preferences.</p>
</div>`,
`<div class="instructionStyle">
<p>Please respond based on your immediate impression of each painting. This part of the experiment will take about 3 minutes.</p>
</div>`,
],
show_clickable_nav: true,
show_page_number: true,
data: {
phase: "evaluation_instructions"
}
}
let human_evaluation_instructions = {
type: jsPsychInstructions,
pages: [
`<div class="instructionStyle">
<p>You will now see a series of abstract paintings created by professional artists, some of which you may have seen before and some that are new.</p>
</div>`,
`<div class="instructionStyle">
<p>For each artist-created painting, please rate how much you like it using the scale provided. There are no right or wrong answers. We're interested in your personal preferences.</p>
</div>`,
`<div class="instructionStyle">
<p>Please respond based on your immediate impression of each painting. This part of the experiment will take about 3 minutes.</p>
</div>`,
],
show_clickable_nav: true,
show_page_number: true,
data: {
phase: "evaluation_instructions"
}
}
let evaluation = {
timeline: [
{
type: jsPsychImageSliderResponse,
stimulus: jsPsych.timelineVariable("image"),
prompt: "<p>How much do you like this painting?</p>",
labels: ["Dislike Very Much", "Like Very Much"],
min: 1,
max: 9,
step: 1,
stimulus_width: 250,
slider_start: 5,
require_movement: true,
post_trial_gap: 200,
data: {
phase: "evaluation"
}
}
],
timeline_variables: [
{image: "images/art/art_1.png"},
{image: "images/art/art_2.png"},
{image: "images/art/art_3.png"},
{image: "images/art/art_4.png"},
{image: "images/art/art_5.png"},
{image: "images/art/art_6.png"},
{image: "images/art/art_7.png"},
{image: "images/art/art_8.png"},
{image: "images/art/art_9.png"},
{image: "images/art/art_10.png"},
{image: "images/art/art_11.png"},
{image: "images/art/art_12.png"}
],
randomized_order: true
}
// ============================================
// Savd Data Trial
// ============================================
const saveData = {
type: jsPsychHtmlKeyboardResponse,
stimulus: `
<div style="text-align: center;">
<p>Experiment complete!</p>
<p>Click the button below to save your data locally:</p>
<button id="save-btn" style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
Click here to save the data locally
</button>
</div>
`,
choices: "NO_KEYS",
trial_duration: null,
on_load: function() {
document.getElementById("save-btn").addEventListener("click", function() {
jsPsych.data.get().localSave("csv", "mereExposure_data.csv");
});
},
data: {
phase: "save data trial"
}
};
// ============================================
// Run jsPsych
// ============================================
if(assigned_condition == "ai"){
// run with ai instructions
jsPsych.run([
welcome,
preload,
ai_exposure_instructions,
exposure,
ai_evaluation_instructions,
evaluation,
saveData
]);
} else if (assigned_condition == "human"){
// run with human instructions
jsPsych.run([
welcome,
preload,
human_exposure_instructions,
exposure,
human_evaluation_instructions,
evaluation,
saveData
]);
}
23.3 Stretch Goals
23.3.1 Add a third between-subjects condition
Let’s add another condition to our experiment. The mere exposure effect for artwork might change due to AI vs. Professional Artists because of perceived skill. Let’s add a third condition that tells participants that the artworks were created by ’amateur artists as a hobby”.
The instructions should read:
- “All of these paintings were created by amateur artists as a hobby…”
- “For each amateur artist-created painting, please rate how much you like it…”
23.3.2 Add a deception debrief
This experiment, although fairly benign, does involve deception. We have lied to some participants, telling them that the paintings were created by artists, when in truth they were all created by an AI image generator.
Let’s two things. Add a deception debrief before the save data screen. This deception screen ONLY needs to be present for the artist/amateur-artist participants. The AI condition has no deception involved.
Here is the text, you can use the instruction plugin and style it properly:
“Deception Notice
Before we finish, we need to inform you about an important aspect of this study:
The labels indicating that the paintings were “Artist-created” was assigned randomly and did not reflect the true source of the paintings. In fact, all images were AI-generated.
This study investigated the “mere exposure effect”: people’s tendency to develop preferences for things they’ve encountered before, even without conscious awareness. We specifically tested whether this effect is influenced by beliefs about whether artwork was created by AI or by human artists.
To answer this question, we needed participants to genuinely believe the source labels. If you had known the labels were random, you would not have formed real beliefs about each painting’s origin, making it impossible to test our hypothesis.”