Forum Discussion
Global scope for Javascript variables in Storyline
As Storyline publishes all code and variables to separate functions in the user.js file the scope for individual variables is local. The solution i show here creates a global scope for functions and variables so you can reuse your Javascript code and variables anywhere in a Storyline project.
Basically i make use of a WebObject to add an external Javascript to Storyline. In that script variables are stored globally so you can reuse them anytime. Also with this solution you can add any custom function to the globalScript.js file. Those functions can then be called from any spot in Storyline.
Lets see it working first.
https://360.articulate.com/review/content/d02ea9a4-b779-4447-befa-7af5a2d02e21/review
In this Storyline you can enter 2 values. A property name and its value. Those will be saved in a Javascript object and can be called with a global function or directly. When adding your first one... it shows in the textfield on the left... then you can continue to the next slide...and do the same... either edit one of the added values...or add a new one.
The function iterateObject(_obj,_desiredoutput); you can use to get your variables and values. Offcourse the argument _obj is for your Object in Javascript. In this case its 'globObj', but you can add as many as you want and customize them. The argument _desiredoutput is for what you want returned. Default that is a string, but you can choose to get an array.
Alright some more info on how it works. As you can see in the Storyline file i use a separate scene for the WebObject that loads the Javascript file(s).
As you can see i use subfolders for my Javascript files. Nothing more then the empty index.html and the globalScripts.js in its own subfolder for the WebObject.
To load the Javascripts files into Storyline i use a Javascript trigger on the start of the timeline. This is probably best added to a Master Slide and ensure its only loaded when the variable 'javascriptsLoaded' is False.
When changing anything to the 'globalScripts.js' or the WebObject you would need to change 2 variables in the script. amountOfLibs and webObjectURL. The latter offcourse refers to the folder Storyline publishes the webObject to. And you would need to publish and check the name of the folder when changing anything.
Then you can call the functions from the 'globalScript.js'. In this sample i only added 2 functions. One to set the variables and one to get them again. Both work on any spot in the Storyline. After the Javascript is loaded you can set and get variables from anywhere in your Storyline.
Do hope this is usefull for some of you.
26 Replies
- JoshuaGarlick-4Community Member
Extremely useful, Math. Thank you again.
- SandeepGadamCommunity Member
Thank you so much for sharing such useful information Math.
- CoriHastingsCommunity Member
Thank you Math! I would love to try this on my current project but with a looming deadline, it's probably not going to happen. Hopefully on the next one!
- Jürgen_Schoene_Community Member
if you wan't to use small solutions for global variables in javascript - use window-variables (storyline is technical a single-page application)
https://javascript.info/global-object
example
javascript trigger 1:
function hallo(){
window.myText = "hallo";
}
javascript trigger 2:
function printHallo(){
console.log( window.myText );
}normaly window variables are not used*, the normal javascript would be
var myText;
function hallo(){
myText = "hallo";
}
function printHallo(){
console.log( myText );
}the result is the same, but this it is not possible in a trigger javascript
Jürgen
* as a developer you should not use such things - global variables are nasty. If you are not careful, they can cause big problems. Normally you encapsulate variables.
- SimonCleary-b95Community Member
This is great, thanks Math.
- steveparadisCommunity Member
Hello Guys,
My personal solution is to use a webObject on the first scene, with sessionStorage.
I do load a webObject (first slide and off stage). the code in the index.html is simply :*************************************
<script>
sessionStorage.setItem("msg_EN","Hello world!");
sessionStorage.setItem("msg_FR","Bonjour le monde!");
sessionStorage.setItem("msg_ES","Hola mundo!");
</script>
*************************************
These become available for each slides even for other webObjects :var player = GetPlayer();
player.SetVar("greetings",sessionStorage.getItem("msg_EN"));
If you care about making the variables more "private", you can always use base64 encode/decode, here is the function I use:
****************************************
function encodeB64(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}function decodeB64(str) {
return decodeURIComponent(atob(str).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}- MathNotermans-9Community Member
Nice solution Steve
- EmmanuelNdlecCommunity Member
Hi all, and particularly @Math.
I'm very interested in this solution, but where can I find your GlobalScript.js file ?
- MathNotermans-9Community Member
As WebObjects keep their files persistent in the Storyline file.. download the globalScope.story.... publish it and magically the js-file is on your computer in the published folder. Instead of previewing...Open Folder and go into story_content/WebObjects/5yVih3lSjPj/globals
and there it is. - EmmanuelNdlecCommunity Member
Thank you so much !
- EmmanuelNdlecCommunity Member
Hi Math,
I'm having hard trying to to make this work, I don't get the console.log messages with my work, while it does appear with your example.
How do you figure the value of webObjectURL ? Do you publish a first time to see the name of the folder the publication process creates, and then rewrite it in the first javascript executed in the first slide, or is there any other way to get that name ?- MathNotermans-9Community Member
Yes. Publish when webObject is added. Open up published folder and copy the name of the folder... and use that in your script. It will only change when deleting and readding your webObject.