如何拦截以弹窗展示的Moodle SCORM活动完成状态?
可以通过PostMessage拦截SCORM完成事件,具体实现分两步走
1. 在SCORM活动内容里监听完成状态并发送消息
SCORM规范中,活动完成时会更新对应状态字段,你可以在SCORM内容的JS代码里检测该状态变化,一旦确认完成,就通过postMessage向父页面发送信号。
- 针对SCORM 1.2:监听
cmi.core.lesson_status字段,当值为completed或passed时触发 - 针对SCORM 2004:监听
cmi.completion_status字段,当值为completed时触发
示例代码(放在SCORM内容的脚本里):
// 获取SCORM API对象(SCORM标准的获取逻辑) function getScormAPI() { let api = null; const findAPI = (win) => { while (win && !win.API) { win = win.parent; if (win === window) break; } return win?.API; }; api = findAPI(window); return api || window.API || window.parent.API; } const scormAPI = getScormAPI(); if (scormAPI) { // 定时检查状态(若无法直接监听字段变化) const checkInterval = setInterval(() => { let status; // 适配不同SCORM版本 try { status = scormAPI.GetValue('cmi.core.lesson_status'); // SCORM 1.2 } catch (e) { status = scormAPI.GetValue('cmi.completion_status'); // SCORM 2004 } if (['completed', 'passed'].includes(status)) { // 发送消息给父页面,生产环境建议替换*为具体域名 window.parent.postMessage( { type: 'scormCompleted', status: status }, '*' ); clearInterval(checkInterval); // 仅发送一次,取消定时 } }, 2000); // 每2秒检查一次 }
2. 父页面监听PostMessage接收完成信号
在嵌入iframe的父页面中,添加message事件监听器,接收SCORM发来的完成通知并执行自定义逻辑:
window.addEventListener('message', (event) => { // 强烈建议校验来源域名,避免恶意消息 if (event.origin !== 'https://你的Moodle域名.com') return; if (event.data.type === 'scormCompleted') { console.log('SCORM活动已完成,状态:', event.data.status); // 这里编写你的拦截逻辑,比如关闭弹窗、更新页面状态等 } });
特殊场景处理
- 无SCORM内容修改权限:可通过Moodle自定义脚本(如主题插件、额外JS注入)在Moodle的SCORM弹窗页面监听状态,再转发消息到父页面。
- 跨域问题:确保
postMessage的targetOrigin设置正确,生产环境不要使用*,指定父页面域名更安全。 - 无代码修改权限的替代方案:使用Moodle的Web服务API定时查询用户的SCORM完成状态,但实时性不如postMessage。
内容的提问来源于stack exchange,提问作者Giovanni Cucè
相关产品推荐
相关产品推荐

