I am creating a webpage with multiple GeoGebra files embedded in it. That means I have, for each GeoGebra applet, a <div>
element in the <body>
with an associated script to configure it; and at the end of the <body>
I have the following script that adds all the applets to their associated <div>
s:
<script>
window.onload = function() {
applet_0.inject('ggb-element-0');
applet_1.inject('ggb-element-1');
applet_2_NoLimit.inject('ggb-element-2-NoLimit');
applet_2_YesLimit.inject('ggb-element-2-YesLimit');
applet_3.inject('ggb-element-3');
applet_4_Flat.inject('ggb-element-4-Flat');
applet_4_Faster.inject('ggb-element-4-Faster');
};
</script>
I noticed that if any of the first six lines of the script fails, for example if the associated file cannot be loaded, all lines following the failed line are not executed.
I want to make this work even if something goes wrong for one of the embeddings. I already discovered that I can't have multiple window.onload
commands (only the last one is executed). Is there an alternative way to make this more fault-tolerant?
Multiple load event handlers
You can have multiple load event listeners by calling window.addEventListener
instead of setting window.onload
. Listeners added in this way are executed in the order they are added. By providing {once: true}
as the third argument the event listener will be removed automatically after being called. The listeners can be added anywhere in code before the load event has been fired that you deem appropriate.
For example the first two listeners could be added by
addEventListener('load', ()=> applet_0.inject('ggb-element-0'), {once: true});
//...
addEventListener('load', ()=> applet_2_NoLimit.inject('ggb-element-2-NoLimit'), {once: true});
// etc...
Single load
event handler
Alternatively if you want to use a single load event handler, say to report errors in a consistent fashion, you could refactor the code to supply applet and string arguments to a single function that does the injection within a try/catch
construct, as for example:
addEventListener( "load", event => {
[
[ applet_0, 'ggb-element-0'],
[ applet_1, 'ggb-element-1'],
[ applet_2_NoLimit, 'ggb-element-2-NoLimit'],
[ applet_2_YesLimit, 'ggb-element-2-YesLimit'],
[ applet_3, 'ggb-element-3'],
[ applet_4_Flat, 'ggb-element-4-Flat'],
[ applet_4_Faster, 'ggb-element-4-Faster'],
]
.forEach( args=> {
const [applet, selector] = args;
try {
applet.inject(selector);
}
catch(err) {
console.log(`injection of ${selector} into applet failed:`, err);
}
})
},
{once: true}
);
If you are unfamiliar with the const [applet, selector] = args;
syntax please see destructuring assignment syntax on MDN.