jsPsych集成Chart.js报e.type非构造函数、缺少type参数错误排查
问题根源
两个报错的核心触发原因是jsPsych时间线的试次节点缺少必填type字段:
- jsPsych要求所有加入timeline数组的试次对象,必须通过
type属性指定对应的渲染插件,你定义的firstGraph、secondGraph两个对象仅写了stimulus回调,没有声明type,直接触发trial level node is missing the "type" parameter报错;后续jsPsych尝试读取不存在的type值作为构造函数初始化,就连带抛出Uncaught TypeError: e.type is not a constructor。 - 代码另外存在两个会导致功能不符合预期的隐藏问题:一是两个canvas元素直接写在静态HTML中,jsPsych运行时默认仅渲染当前激活试次的内容,提前写入的canvas不会在对应流程节点展示;二是Chart.js版本语法不匹配,你引入的是2.x版本的Chart.js,但第一个图表的坐标轴配置用了3.x以上版本才支持的写法,即使解决type报错也会出现图表渲染异常。
修复步骤
- 给
firstGraph、secondGraph两个试次补上type: jsPsychHtmlKeyboardResponse,和欢迎页使用同一个插件即可,该插件支持自定义HTML内容、监听按键响应推进流程。 - 移除HTML中静态写入的两个canvas元素,将canvas的HTML代码放到对应试次的
stimulus回调返回值中,jsPsych会在运行到对应试次时自动把canvas插入页面。 - 把Chart实例初始化的逻辑放到试次的
on_load回调里执行,确保DOM节点已经渲染完成后再初始化图表,避免找不到元素的报错。 - 统一Chart.js语法,将第一个图表的坐标轴配置改为2.x版本兼容的写法,匹配你引入的CDN资源版本。
- 给两个图表试次添加
choices: "ALL_KEYS"配置,实现用户看完图表按任意键进入下一个环节的交互逻辑。
修正后完整代码
HTML部分
移除原来静态放置的canvas标签,仅保留资源引入:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script> <script src="https://unpkg.com/jspsych@7.2.3" ></script> <script src="https://unpkg.com/@jspsych/plugin-html-keyboard-response@1.1.1" ></script> <link rel="stylesheet" href="https://unpkg.com/jspsych@7.2.3/css/jspsych.css" type="text/css" >
JavaScript部分
var jsPsych = initJsPsych({}); var timeline = []; var welcome = { type: jsPsychHtmlKeyboardResponse, stimulus: "Hey there! Let's view some cool graphs. Press any key to continue." }; timeline.push(welcome); var firstGraph = { type: jsPsychHtmlKeyboardResponse, stimulus: function () { return `<canvas id="myChart"></canvas>`; }, on_load: function() { const ctx = document.getElementById('myChart'); const myChart = new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Green'], datasets: [{ label: '# of Votes', data: [12, 5], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(75, 192, 192, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(75, 192, 192, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: true } }] } } }) }, choices: "ALL_KEYS" }; timeline.push(firstGraph); var secondGraph = { type: jsPsychHtmlKeyboardResponse, stimulus: function() { return `<canvas id="twoChart"></canvas>`; }, on_load: function() { var ctx = document.getElementById("twoChart").getContext('2d'); var dataValues = [12, 19, 3, 5]; var dataLabels = [0, 1, 2, 3, 4]; var twoChart = new Chart(ctx, { type: 'bar', data: { labels: dataLabels, datasets: [{ label: 'Group A', data: dataValues, backgroundColor: 'rgba(255, 99, 132, 1)', }] }, options: { scales: { xAxes: [{ display: false, barPercentage: 1.3, ticks: { max: 3, } }, { display: true, ticks: { autoSkip: false, max: 4, } }], yAxes: [{ ticks: { beginAtZero:true } }] } } }) }, choices: "ALL_KEYS" }; timeline.push(secondGraph); jsPsych.run(timeline);
内容的提问来源于stack exchange,提问作者codebaby
相关产品推荐
相关产品推荐

