You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于参与者响应在jsPsych时间线中动态添加事件?

在jsPsych中根据参与者响应动态插入时间线事件

核心问题分析

你之前的尝试失败原因:

  • 直接修改timeline数组(push/splice)无效:jsPsych调用run()后会创建时间线的内部副本,修改原始数组不会影响正在执行的流程。
  • jsPsych.addNodeToEndOfTimeline会把Message加到当前时间线末尾,但你提前把Conclusion也加入了时间线,导致Message出现在Conclusion之后,不符合需求。

解决方案一:使用官方条件分支节点(推荐)

jsPsych内置了条件分支支持,通过conditional_function可以控制某个时间线节点是否执行,这是处理这类流程的标准方式,无需手动修改时间线。

完整可运行代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Experiment</title>
  <script src="https://unpkg.com/jspsych@7.3.3"></script>
  <script src="https://unpkg.com/@jspsych/plugin-html-keyboard-response@1.1.2"></script>
  <script src="https://unpkg.com/@jspsych/plugin-html-button-response@1.1.2"></script>
  <link href="https://unpkg.com/jspsych@7.3.3/css/jspsych.css" rel="stylesheet" type="text/css" />
</head>
<body style="background-color: rgb(200, 200, 200);">
<script>
// 初始化jsPsych
var jsPsych = initJsPsych();

// 随机化选项顺序
var choice = jsPsych.randomization.sampleWithoutReplacement(['A', 'B', 'C'], 3);  

// 定义各个试次
var Message = {
  type: jsPsychHtmlKeyboardResponse,
  stimulus: 'Congrats, It worked! Press Space to Continue',
  choices: [' '],
};

var Conclusion = {
  type: jsPsychHtmlKeyboardResponse,
  stimulus: 'The experiment Ended! Press Space to Continue',
  choices: [' '],
};

var ChoiceTrial = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Choose A to end, or B or C to see a message',
  choices: choice,
};

// 定义条件分支节点:仅当选择非A时执行Message
var conditionalMessageNode = {
  timeline: [Message],
  conditional_function: function() {
    // 获取上一个试次的响应结果
    var lastResponse = jsPsych.data.get().last(1).values()[0].response;
    // 返回true则执行当前时间线节点,false则跳过
    return lastResponse !== 'A';
  }
};

// 构建主时间线:ChoiceTrial → 条件Message → Conclusion
var timeline = [ChoiceTrial, conditionalMessageNode, Conclusion];

// 运行实验
jsPsych.run(timeline);
</script>
</body>
</html>

关键逻辑说明

  • conditionalMessageNode作为中间节点,通过conditional_function检查上一个试次的响应:如果选择的不是A,就执行Message试次;如果是A,则直接跳过,进入Conclusion。
  • 这种方式完全遵循jsPsych的流程设计,代码清晰且不易出错。

解决方案二:动态修改正在运行的时间线(适合复杂场景)

如果需要更灵活的动态插入(比如复杂分支逻辑),可以通过操作jsPsych的内部时间线节点实现,核心是先调整后续节点的顺序,再插入新节点:

关键代码修改

var ChoiceTrial = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Choose A to end, or B or C to see a message',
  choices: choice,
  on_finish: function (data) {
    if(data.response !== 'A'){
      // 获取主时间线节点
      var mainTimeline = jsPsych.getTimelineNodeChildren(jsPsych.getMainTimelineNode())[0];
      // 移除已经添加的Conclusion节点
      mainTimeline.children.pop();
      // 插入Message节点
      jsPsych.addNodeToEndOfTimeline({timeline: [Message]}, mainTimeline);
      // 重新添加Conclusion节点
      jsPsych.addNodeToEndOfTimeline({timeline: [Conclusion]}, mainTimeline);
    }
  }
};

// 初始时间线仅包含ChoiceTrial和Conclusion
var timeline = [ChoiceTrial, Conclusion];
jsPsych.run(timeline);

逻辑说明

  • 在ChoiceTrial的on_finish回调中,先移除已在时间线末尾的Conclusion,插入Message后再重新添加Conclusion,确保Message出现在Conclusion之前。
  • 这种方式适合复杂动态场景,但需要注意时间线节点的层级关系,避免操作错误。

内容的提问来源于stack exchange,提问作者William Mitchell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:35:34