3个高效步骤:使用jsPsych构建专业行为实验的完整指南
问题:行为实验开发的核心挑战
在行为科学研究中,研究者常常面临三大核心挑战:如何精确测量反应时数据、如何确保实验在不同设备上的一致性、以及如何高效处理实验流程中的复杂逻辑。传统实验开发往往需要专业的编程知识和繁琐的设备配置,这使得许多研究者将大量时间耗费在技术实现而非实验设计本身。
jsPsych作为一款专为行为实验设计的JavaScript库,通过插件化架构和精确的计时系统,为解决这些问题提供了完整方案。本指南将采用"问题-方案-实践"框架,帮助你快速掌握jsPsych的核心功能,构建专业、可靠的行为实验。
方案:模块化实验开发路径
1. 环境搭建与核心概念
1.1 快速安装与项目配置
需求场景:从零开始搭建jsPsych实验环境,确保所有依赖正确配置。
技术原理:jsPsych采用模块化设计,核心库提供基础功能,插件扩展特定实验范式。通过npm安装可确保依赖管理的规范性。
代码实现:
# 克隆官方仓库
git clone https://gitcode.com/gh_mirrors/js/jsPsych
# 进入项目目录
cd jsPsych
# 安装依赖
npm install
# 启动开发服务器
npm run start
效果验证:访问http://localhost:8080/examples/,查看示例实验是否正常运行。
1.2 实验基本结构
需求场景:理解jsPsych实验的基本组成部分,创建第一个最小化实验。
技术原理:每个jsPsych实验由timeline(时间线)和trial(试次)构成,通过插件定义不同类型的实验任务。
代码实现:
<!DOCTYPE html>
<html>
<head>
<title>最小化jsPsych实验</title>
<script src="node_modules/jspsych/dist/jspsych.js"></script>
<link rel="stylesheet" href="node_modules/jspsych/css/jspsych.css">
</head>
<body></body>
<script>
// 创建欢迎试次
const welcome = {
type: 'html-keyboard-response',
stimulus: '欢迎参加实验!按任意键开始。',
post_trial_gap: 500 // 试次间间隔500毫秒
};
// 创建实验试次
const trial = {
type: 'html-keyboard-response',
stimulus: '看到"GO"按空格键,看到"NO"不按键',
choices: [' '], // 只允许空格键反应
trial_duration: 1500, // 1500毫秒后自动进入下一试次
data: {task: 'go_no_go'} // 添加自定义数据字段
};
// 创建结束试次
const goodbye = {
type: 'html-keyboard-response',
stimulus: '实验结束,谢谢参与!',
choices: jsPsych.NO_KEYS // 不需要按键反应
};
// 构建时间线
const timeline = [welcome, trial, goodbye];
// 初始化实验
jsPsych.init({
timeline: timeline,
on_finish: function() {
// 实验结束后显示数据
jsPsych.data.displayData();
}
});
</script>
</html>
效果验证:在浏览器中打开该HTML文件,观察实验流程是否符合预期,结束后是否正确显示数据。
1.3 术语卡片:Timeline与Trial
定义:Timeline是实验流程的有序集合,由一个或多个Trial组成;Trial是实验的基本单元,定义单次实验任务。
使用场景:所有jsPsych实验都基于Timeline组织,复杂实验可通过嵌套Timeline实现分支逻辑。
注意事项:
- Timeline中的试次按顺序执行
- 可通过conditional_function实现条件分支
- 可通过loop_function实现循环结构
- 试次间默认无间隔,需通过post_trial_gap设置
2. 核心功能实现
2.1 反应时测量实验
需求场景:创建一个视觉刺激反应时实验,精确测量从刺激呈现到按键反应的时间。
技术原理:jsPsych的键盘反应插件提供毫秒级精度的反应时记录,通过stimulus参数呈现刺激,choices参数限制允许的按键。
代码实现:
// 定义实验材料
const stimuli = [
{word: '红色', color: 'red'},
{word: '蓝色', color: 'blue'},
{word: '绿色', color: 'green'},
{word: '黄色', color: 'yellow'}
];
// 创建 Stroop 实验试次
const stroop_trial = {
type: 'html-keyboard-response',
stimulus: function() {
// 随机选择一个刺激
const stimulus = jsPsych.randomization.sampleWithoutReplacement(stimuli, 1)[0];
// 保存刺激信息到数据中
jsPsych.data.addDataToLastTrial({
word: stimulus.word,
color: stimulus.color,
congruent: stimulus.word === stimulus.color
});
// 返回带颜色的文字刺激
return `<div style="font-size: 48px; color: ${stimulus.color};">${stimulus.word}</div>`;
},
choices: ['r', 'b', 'g', 'y'], // 分别对应红、蓝、绿、黄
prompt: `<p>请按对应颜色的键:R=红,B=蓝,G=绿,Y=黄</p>`,
data: {task: 'stroop'},
on_finish: function(data) {
// 判断反应是否正确
const correct_key = {
'red': 'r',
'blue': 'b',
'green': 'g',
'yellow': 'y'
}[data.color];
data.correct = data.response === correct_key;
}
};
// 创建实验时间线
const timeline = [
{
type: 'html-keyboard-response',
stimulus: 'Stroop实验准备开始!按任意键继续。'
},
{
timeline: [stroop_trial],
repetitions: 12, // 重复12次实验试次
randomize_order: true // 随机化试次顺序
},
{
type: 'html-keyboard-response',
stimulus: function() {
const data = jsPsych.data.get().filter({task: 'stroop'});
const correct = data.filter({correct: true}).count();
const accuracy = (correct / data.count() * 100).toFixed(1);
const rt = data.filter({correct: true}).select('rt').mean().toFixed(0);
return `实验结束!<br>正确率: ${accuracy}%<br>平均反应时: ${rt}ms`;
}
}
];
// 初始化实验
jsPsych.init({
timeline: timeline,
show_progress_bar: true,
message_progress_bar: '实验进度'
});
效果验证:运行实验,观察是否正确呈现颜色词刺激,结束后是否显示正确的正确率和平均反应时。
带有进度条的Stroop实验界面,显示当前完成进度和当前试次刺激
2.2 多设备响应式设计
需求场景:确保实验在桌面和移动设备上都能正常运行,界面元素自适应不同屏幕尺寸。
技术原理:jsPsych内置响应式设计支持,结合CSS媒体查询可实现完全适配各种设备的实验界面。
代码实现:
<!DOCTYPE html>
<html>
<head>
<title>响应式jsPsych实验</title>
<script src="node_modules/jspsych/dist/jspsych.js"></script>
<link rel="stylesheet" href="node_modules/jspsych/css/jspsych.css">
<style>
/* 基础样式 */
.jspsych-content {
max-width: 800px;
}
/* 刺激样式 */
.stimulus {
font-size: 4vw; /* 使用视窗宽度单位,自动适应屏幕 */
margin: 20px 0;
}
/* 按钮样式 */
.jspsych-btn {
padding: 15px 30px;
font-size: 1.2em;
margin: 10px;
}
/* 移动设备适配 */
@media (max-width: 768px) {
.stimulus {
font-size: 8vw;
}
.jspsych-btn {
display: block;
width: 80%;
margin: 10px auto;
padding: 12px;
}
}
</style>
</head>
<body></body>
<script>
// 浏览器检查试次
const browser_check = {
type: 'browser-check',
minimum_width: 320,
minimum_height: 480,
message: '您的设备或浏览器不支持本实验,请使用屏幕尺寸更大的设备或更新浏览器。'
};
// 响应式问卷试次
const survey_trial = {
type: 'survey-likert',
questions: [
{
prompt: '这个实验界面在您的设备上显示是否正常?',
labels: ['非常不正常', '不太正常', '一般', '比较正常', '非常正常'],
required: true
},
{
prompt: '您使用的设备类型是?',
labels: ['手机', '平板', '笔记本电脑', '台式电脑'],
required: true
}
],
randomize_question_order: false
};
// 时间线
const timeline = [browser_check, survey_trial];
// 初始化实验
jsPsych.init({
timeline: timeline,
on_finish: function() {
jsPsych.data.displayData();
}
});
</script>
</html>
效果验证:在不同设备或浏览器开发者工具的不同设备模式下测试,观察界面元素是否正确适配。
jsPsych调查插件自动适配移动和桌面设备,确保实验在各种终端上都有良好表现
2.3 数据收集与导出
需求场景:收集实验数据并以多种格式导出,便于后续分析。
技术原理:jsPsych提供全面的数据API,可获取、筛选和转换实验数据,支持CSV、JSON等多种格式导出。
代码实现:
// 定义简单的反应时实验
const trial = {
type: 'image-keyboard-response',
stimulus: function() {
return jsPsych.randomization.sampleWithoutReplacement(
['examples/img/blue.png', 'examples/img/orange.png'], 1
)[0];
},
choices: ['f', 'j'],
prompt: '<p>看到蓝色按F键,看到橙色按J键</p>',
data: {task: 'color_discrimination'}
};
// 实验结束处理
const end_experiment = {
type: 'html-keyboard-response',
stimulus: '实验结束!按任意键查看结果。',
on_finish: function() {
// 获取所有实验数据
const all_data = jsPsych.data.get();
// 筛选特定任务数据
const task_data = all_data.filter({task: 'color_discrimination'});
// 计算基本统计量
const accuracy = task_data.filter({correct: true}).count() / task_data.count() * 100;
const mean_rt = task_data.filter({correct: true}).select('rt').mean();
// 显示结果
const results = `
<h2>实验结果</h2>
<p>正确率: ${accuracy.toFixed(1)}%</p>
<p>平均反应时: ${mean_rt.toFixed(0)}ms</p>
<button onclick="downloadCSV()">下载CSV数据</button>
<button onclick="downloadJSON()">下载JSON数据</button>
`;
document.querySelector('#jspsych-content').innerHTML = results;
// 定义下载函数
window.downloadCSV = function() {
const csv = all_data.csv();
const blob = new Blob([csv], {type: 'text/csv'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'experiment_data_' + new Date().toISOString().slice(0,10) + '.csv';
a.click();
};
window.downloadJSON = function() {
const json = all_data.json();
const blob = new Blob([json], {type: 'application/json'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'experiment_data_' + new Date().toISOString().slice(0,10) + '.json';
a.click();
};
}
};
// 时间线
const timeline = [
{
type: 'html-keyboard-response',
stimulus: '颜色辨别实验准备开始!按任意键继续。'
},
{
timeline: [trial],
repetitions: 10,
randomize_order: true
},
end_experiment
];
// 初始化实验
jsPsych.init({
timeline: timeline
});
效果验证:完成实验后,点击下载按钮,检查是否成功生成包含所有试次数据的CSV和JSON文件。
3. 进阶拓展与优化
3.1 实验流程控制
需求场景:实现基于被试表现的自适应实验流程,如根据正确率调整难度。
技术原理:通过conditional_function和loop_function实现条件分支和循环控制,动态调整实验流程。
代码实现:
// 定义不同难度的刺激
const easy_stimuli = [
{word: '猫', color: 'black'},
{word: '狗', color: 'black'},
{word: '鸟', color: 'black'}
];
const hard_stimuli = [
{word: '红', color: 'blue'},
{word: '蓝', color: 'green'},
{word: '绿', color: 'red'}
];
// 初始化难度和分数
let current_difficulty = 'easy';
let score = 0;
// 难度调整试次
const difficulty_adjustment = {
type: 'html-keyboard-response',
stimulus: function() {
return `<p>当前分数: ${score}/10</p><p>按任意键继续</p>`;
},
on_finish: function() {
// 根据分数调整难度
if (score >= 8) {
current_difficulty = 'hard';
} else if (score <= 3) {
current_difficulty = 'easy';
}
// 重置分数
score = 0;
}
};
// 实验试次
const trial = {
type: 'html-keyboard-response',
stimulus: function() {
// 根据当前难度选择刺激
const stimuli = current_difficulty === 'easy' ? easy_stimuli : hard_stimuli;
const stimulus = jsPsych.randomization.sampleWithoutReplacement(stimuli, 1)[0];
jsPsych.data.addDataToLastTrial({
difficulty: current_difficulty,
word: stimulus.word,
color: stimulus.color
});
return `<div style="font-size: 48px; color: ${stimulus.color};">${stimulus.word}</div>`;
},
choices: ['f', 'j'],
prompt: '<p>看到动物名称按F键,看到颜色名称按J键</p>',
on_finish: function(data) {
// 判断反应是否正确
const is_animal = ['猫', '狗', '鸟'].includes(data.word);
const correct_response = is_animal ? 'f' : 'j';
data.correct = data.response === correct_response;
// 更新分数
if (data.correct) score++;
}
};
// 循环节点
const practice_loop = {
timeline: [trial],
repetitions: 10,
loop_function: function(data) {
// 每完成10个试次后检查是否继续
const total_trials = jsPsych.data.get().filter({task: 'classification'}).count();
return total_trials < 30; // 最多完成30个试次
}
};
// 完整时间线
const timeline = [
{
type: 'html-keyboard-response',
stimulus: '自适应难度实验准备开始!按任意键继续。'
},
{
timeline: [practice_loop, difficulty_adjustment],
loop_function: function() {
// 继续循环直到完成30个试次
const total_trials = jsPsych.data.get().filter({task: 'classification'}).count();
return total_trials < 30;
}
},
{
type: 'html-keyboard-response',
stimulus: function() {
const data = jsPsych.data.get().filter({task: 'classification'});
const correct = data.filter({correct: true}).count();
const accuracy = (correct / data.count() * 100).toFixed(1);
return `实验结束!总正确率: ${accuracy}%`;
}
}
];
// 初始化实验
jsPsych.init({
timeline: timeline,
show_progress_bar: true
});
效果验证:运行实验,观察是否根据表现正确调整难度,高分时难度增加,低分时难度降低。
3.2 样式自定义与品牌化
需求场景:自定义实验界面样式,使其符合研究项目的品牌风格或特定视觉要求。
技术原理:通过自定义CSS覆盖默认样式,使用浏览器开发者工具定位和修改元素样式。
代码实现:
<!DOCTYPE html>
<html>
<head>
<title>自定义样式实验</title>
<script src="node_modules/jspsych/dist/jspsych.js"></script>
<link rel="stylesheet" href="node_modules/jspsych/css/jspsych.css">
<style>
/* 全局样式 */
body {
font-family: 'Arial', sans-serif;
background-color: #f0f4f8;
color: #333;
}
/* 进度条样式 */
#jspsych-progressbar-container {
background-color: #e1e5eb;
border-radius: 10px;
padding: 5px;
margin-bottom: 20px;
}
#jspsych-progressbar-complete {
background-color: #4c6ef5;
height: 10px;
border-radius: 5px;
transition: width 0.3s ease;
}
/* 刺激区域样式 */
.jspsych-content {
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: white;
border-radius: 15px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
/* 刺激文本样式 */
.custom-stimulus {
font-size: 36px;
font-weight: bold;
text-align: center;
margin: 40px 0;
padding: 20px;
border-radius: 10px;
background-color: #f8f9fa;
border: 2px solid #dee2e6;
}
/* 按钮样式 */
.jspsych-btn {
background-color: #4c6ef5;
color: white;
border: none;
padding: 12px 24px;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.2s;
}
.jspsych-btn:hover {
background-color: #3b5bdb;
}
.jspsych-btn:active {
background-color: #2d4cc8;
}
</style>
</head>
<body></body>
<script>
// 创建自定义样式的试次
const custom_trial = {
type: 'html-button-response',
stimulus: '<div class="custom-stimulus">请选择您偏好的颜色</div>',
choices: ['红色', '蓝色', '绿色'],
button_html: '<button class="jspsych-btn" style="background-color: %choice%;">%choice%</button>',
data: {task: 'preference'}
};
// 时间线
const timeline = [
{
type: 'html-keyboard-response',
stimulus: '<div class="custom-stimulus">自定义样式实验</div><p>按任意键开始</p>'
},
custom_trial,
{
type: 'html-keyboard-response',
stimulus: function() {
const response = jsPsych.data.get().last(1).values()[0].response;
return `<div class="custom-stimulus">您选择了: ${response}</div><p>实验结束,谢谢参与!</p>`
}
}
];
// 初始化实验
jsPsych.init({
timeline: timeline,
show_progress_bar: true,
message_progress_bar: '实验进度'
});
</script>
</html>
效果验证:运行实验,观察界面是否应用了自定义样式,按钮颜色是否正确显示,进度条样式是否符合预期。
使用浏览器开发者工具查看和修改jsPsych元素样式,实现自定义界面设计
3.3 性能优化与错误处理
需求场景:优化实验性能,确保在各种设备上流畅运行,并处理可能出现的错误。
技术原理:通过资源预加载、错误捕获和性能监控,提升实验的可靠性和稳定性。
代码实现:
// 预加载资源
const preload = {
type: 'preload',
images: [
'examples/img/blue.png',
'examples/img/orange.png',
'examples/img/happy_face_1.jpg',
'examples/img/sad_face_1.jpg'
],
audio: [
'examples/sound/tone.mp3',
'examples/sound/hammer.mp3'
],
show_progress_bar: true,
message: '正在加载实验资源,请稍候...',
on_error: function(file) {
// 资源加载错误处理
console.error('资源加载失败:', file);
jsPsych.endExperiment(`实验资源加载失败: ${file}. 请刷新页面重试。`);
}
};
// 性能监控试次
const performance_check = {
type: 'call-function',
func: function() {
// 检查浏览器性能
if (!window.performance) {
console.warn('浏览器不支持性能监控');
return;
}
// 记录初始性能数据
const perfData = performance.timing;
const loadTime = perfData.loadEventEnd - perfData.navigationStart;
// 如果加载时间过长,显示警告
if (loadTime > 5000) {
jsPsych.data.addDataToLastTrial({
warning: '页面加载时间过长',
load_time_ms: loadTime
});
}
}
};
// 实验试次
const trial = {
type: 'image-keyboard-response',
stimulus: function() {
return jsPsych.randomization.sampleWithoutReplacement(
['examples/img/happy_face_1.jpg', 'examples/img/sad_face_1.jpg'], 1
)[0];
},
choices: ['h', 's'],
prompt: '<p>看到开心的脸按H键,看到悲伤的脸按S键</p>',
trial_duration: 2000,
on_load: function() {
// 试次加载时播放提示音
try {
const audio = new Audio('examples/sound/tone.mp3');
audio.play().catch(e => {
console.warn('音频播放失败:', e);
// 不中断实验,仅记录错误
jsPsych.data.addDataToLastTrial({audio_error: e.message});
});
} catch (e) {
console.error('音频初始化失败:', e);
jsPsych.data.addDataToLastTrial({audio_init_error: e.message});
}
},
on_finish: function(data) {
// 检查反应时是否异常
if (data.rt && (data.rt < 100 || data.rt > 1500)) {
data.rt_outlier = true;
} else {
data.rt_outlier = false;
}
}
};
// 时间线
const timeline = [
preload,
performance_check,
{
type: 'html-keyboard-response',
stimulus: '表情识别实验准备开始!按任意键继续。'
},
{
timeline: [trial],
repetitions: 8,
randomize_order: true
},
{
type: 'html-keyboard-response',
stimulus: '实验结束,谢谢参与!'
}
];
// 初始化实验
jsPsych.init({
timeline: timeline,
show_progress_bar: true,
on_error: function(error) {
// 全局错误处理
console.error('实验发生错误:', error);
alert(`实验发生错误: ${error.message}\n请刷新页面重试。`);
}
});
💡 性能优化提示:
- 图片资源建议使用WebP格式,平均比JPEG小30%
- 预加载资源时使用适当的缓存策略
- 对于大型实验,考虑分阶段加载资源
- 避免在试次中使用复杂的DOM操作
- 使用requestAnimationFrame更新视觉刺激,确保平滑渲染
效果验证:监控实验加载时间,检查在资源加载失败时是否正确显示错误信息,反应时异常值是否被标记。
实践:痛点解决与学习路径
痛点解决专栏
痛点1:媒体资源加载失败
问题描述:实验中图片或音频资源加载失败,导致实验无法正常进行。
解决方案:
- 使用preload插件显式预加载所有媒体资源
- 实现错误处理函数,捕获加载失败并提供友好提示
- 使用CDN或本地缓存策略提高资源加载可靠性
- 对大型资源进行压缩和格式优化
代码示例:
const preload = {
type: 'preload',
images: ['img/stimulus1.jpg', 'img/stimulus2.jpg'],
audio: ['sound/feedback.mp3'],
on_error: function(file) {
// 记录错误并尝试替代资源
console.error('资源加载失败:', file);
const fallback_files = {
'img/stimulus1.jpg': 'img/fallback/stimulus1.jpg',
'img/stimulus2.jpg': 'img/fallback/stimulus2.jpg'
};
// 如果有备选资源,尝试加载
if (fallback_files[file]) {
return fallback_files[file];
}
// 没有备选资源时结束实验
jsPsych.endExperiment(`无法加载必要的实验资源: ${file}\n请检查网络连接后重试。`);
}
};
痛点2:移动设备触摸反应问题
问题描述:在移动设备上,触摸反应延迟或误触,影响数据准确性。
解决方案:
- 使用专门针对触摸设备优化的插件
- 增加触摸目标大小,至少48x48像素
- 添加防误触机制,如触摸延迟确认
- 针对移动设备调整刺激呈现时间
代码示例:
const touch_optimized_trial = {
type: 'html-button-response',
stimulus: '触摸下方按钮',
choices: ['按钮1', '按钮2', '按钮3'],
button_html: '<button class="jspsych-btn" style="min-width: 120px; min-height: 60px; font-size: 20px;">%choice%</button>',
trial_duration: 3000,
post_trial_gap: 500,
on_load: function() {
// 防止双击缩放
document.addEventListener('touchstart', function(e) {
if (e.touches.length > 1) {
e.preventDefault();
}
}, {passive: false});
// 防止触摸滚动
document.body.style.touchAction = 'manipulation';
}
};
痛点3:数据丢失风险
问题描述:实验过程中意外关闭浏览器或网络中断,导致数据丢失。
解决方案:
- 定期自动保存数据到localStorage
- 实现数据恢复机制,允许从上次中断处继续实验
- 提供手动保存选项
- 实验结束后立即上传数据到服务器
代码示例:
// 自动保存数据
const auto_save = {
type: 'call-function',
func: function() {
const data = jsPsych.data.get().json();
localStorage.setItem('experiment_auto_save', data);
localStorage.setItem('last_save_time', new Date().toISOString());
},
timing: 'every_trial' // 每个试次后执行
};
// 检查是否有保存的数据
const check_for_saved_data = {
type: 'call-function',
func: function() {
const saved_data = localStorage.getItem('experiment_auto_save');
const last_save = localStorage.getItem('last_save_time');
if (saved_data && last_save) {
const days_since_save = (new Date() - new Date(last_save)) / (1000 * 60 * 60 * 24);
// 如果有保存的数据且不超过1天,询问是否恢复
if (days_since_save < 1) {
const restore = confirm('检测到上次未完成的实验数据,是否恢复?');
if (restore) {
const data = JSON.parse(saved_data);
jsPsych.data.reset();
jsPsych.data.add(data);
console.log('已恢复保存的数据');
}
} else {
// 超过1天的旧数据,清除
localStorage.removeItem('experiment_auto_save');
localStorage.removeItem('last_save_time');
}
}
}
};
// 实验结束时上传数据
const upload_data = {
type: 'call-function',
func: function() {
const data = jsPsych.data.get().json();
// 发送数据到服务器
fetch('/api/save-data', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
subject_id: jsPsych.randomization.randomID(10),
data: data,
timestamp: new Date().toISOString()
})
})
.then(response => response.json())
.then(result => {
if (result.success) {
console.log('数据上传成功');
// 上传成功后清除本地保存
localStorage.removeItem('experiment_auto_save');
localStorage.removeItem('last_save_time');
} else {
console.error('数据上传失败', result.error);
// 上传失败时提示用户手动保存
alert('数据上传失败,请手动保存您的实验数据。');
jsPsych.data.displayData();
}
})
.catch(error => {
console.error('数据上传错误:', error);
alert('数据上传错误,请手动保存您的实验数据。');
jsPsych.data.displayData();
});
}
};
学习路径图
入门阶段(1-2周)
-
基础概念:理解Timeline、Trial和插件系统
-
核心插件:掌握5个最常用插件
- html-keyboard-response
- image-keyboard-response
- survey-likert
- instructions
- preload
-
数据收集:学习基本数据记录和导出方法
进阶阶段(2-4周)
-
实验控制:掌握条件分支和循环结构
-
样式定制:学习自定义CSS和响应式设计
-
性能优化:资源预加载和性能监控
高级阶段(1-2个月)
-
插件开发:创建自定义实验插件
-
扩展功能:使用jsPsych扩展(如眼动追踪)
-
高级数据处理:实时数据传输和数据库集成
工具推荐对比
| 工具类型 | 推荐工具 | 优势 | 适用场景 |
|---|---|---|---|
| 代码编辑器 | VS Code | 轻量级,插件丰富,支持调试 | 所有jsPsych开发 |
| 版本控制 | Git | 跟踪代码变化,协作开发 | 团队项目,长期开发 |
| 数据可视化 | D3.js | 高度可定制,适合科研数据展示 | 实验结果可视化 |
| 统计分析 | R + jsPsychR | 专业统计分析,与jsPsych无缝集成 | 实验数据分析 |
| 在线部署 | Netlify | 简单部署,免费计划可用 | 小规模实验发布 |
| 参与者管理 | Prolific | 高质量被试池,内置支付系统 | 需要招募被试的研究 |
总结
通过本文介绍的"问题-方案-实践"框架,你已经掌握了使用jsPsych构建专业行为实验的核心技能。从环境搭建到高级功能实现,再到性能优化和错误处理,我们覆盖了实验开发的全流程。
记住,优秀的行为实验不仅需要精确的数据收集,还需要良好的用户体验和可靠的性能。通过合理使用jsPsych的插件系统和时间线控制,结合本文提供的痛点解决方案,你可以构建出既科学严谨又用户友好的行为实验。
现在,是时候将这些知识应用到你的研究项目中了。从简单的反应时实验开始,逐步尝试更复杂的实验设计,不断探索jsPsych的强大功能。祝你在行为科学研究中取得丰硕成果!
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
LongCat-AudioDiT-1BLongCat-AudioDiT 是一款基于扩散模型的文本转语音(TTS)模型,代表了当前该领域的最高水平(SOTA),它直接在波形潜空间中进行操作。00- QQwen3.5-397B-A17BQwen3.5 实现了重大飞跃,整合了多模态学习、架构效率、强化学习规模以及全球可访问性等方面的突破性进展,旨在为开发者和企业赋予前所未有的能力与效率。Jinja00
HY-Embodied-0.5这是一套专为现实世界具身智能打造的基础模型。该系列模型采用创新的混合Transformer(Mixture-of-Transformers, MoT) 架构,通过潜在令牌实现模态特异性计算,显著提升了细粒度感知能力。Jinja00
FreeSql功能强大的对象关系映射(O/RM)组件,支持 .NET Core 2.1+、.NET Framework 4.0+、Xamarin 以及 AOT。C#00