SCORM courses use JavaScript to send data to the LMS. This data then sits in the browser until the LMS writes it to the database (usually via AJAX or form posts). As previously discussed, invoking commit
(save) will ensure the LMS actually writes this data to a database.
But what happens if the browser window containing your course is closed by the learner before the course finishes sending data to the LMS? If you’re not careful about how you’ve coded your course, you can lose some of the data. For example, if a learner completes the course and then immediately closes the window, the course might not have had enough time to tell the LMS about the completion, preventing the completion from appearing in the learner’s record.
It’s best to be proactive about this by setting up an event handler for the browser’s unload
and onbeforeunload
events. Whatever code you place in these events will execute when the browser is closed. In a SCORM course, you should place a commit
(save) and terminate
(quit) command in these events to ensure the SCORM data is properly persisted in the database and the session is properly terminated.
The code is pretty straightforward (this example uses SCORM 2004):
//Assuming API refers to your SCORM API
//and API_isActive returns a boolean indicating
//whether your API has already been terminated
var unloaded = false;
function unloadHandler(){
if(!unloaded && API_isActive){
API.SetValue("cmi.exit", "suspend"); //Set exit to whatever is needed
API.Commit(""); //save all data that has already been sent
API.Terminate(""); //close the SCORM API connection properly
unloaded = true;
}
}
window.onbeforeunload = unloadHandler;
window.onunload = unloadHandler;
Code language: JavaScript (javascript)
Since some browsers support onbeforeunload
and others don’t, we use the unloadHandler
on both onbeforeunload
and onunload
, just to be safe. If a browser supports both of these events, the unloaded
boolean ensures the scorm.quit
function is not executed more than once.
If you’re using the pipwerks SCORM wrapper, your code will be even simpler, because the pipwerks wrapper automatically checks the API’s availability before performing any action. The wrapper also sets the cmi.exit
/cmi.core.exit
parameter for you.
var unloaded = false;
function unloadHandler(){
if(!unloaded){
scorm.save(); //save all data that has already been sent
scorm.quit(); //close the SCORM API connection properly
unloaded = true;
}
}
window.onbeforeunload = unloadHandler;
window.onunload = unloadHandler;
Code language: JavaScript (javascript)
Comments
Tim Martin wrote on August 6, 2010 at 7:38 am:
Don't miss an important piece of what Philip did here, either… He defends against Terminating twice by checking the variable unloaded. A lot of people making use of onunload and onbeforeunload fail to do so, creating API calls against an unloaded API.
Don’t miss an important piece of what Philip did here, either… He defends against Terminating twice by checking the variable unloaded. A lot of people making use of onunload and onbeforeunload fail to do so, creating API calls against an unloaded API.