I created a game a while back for SL2, my external JS file gets and sets a bunch of Storyline variables using GetPlayer, SetVar and GetVar.
With the release of SL3, I have published this same game out, the Flash version works fine, the HTML5 version however, does not work. I am getting a ReferenceError on GetPlayer.
Does anyone know what the function to grab the SL player has changed to? I have gone through most of the given code, but I can't find any direct references to it anymore.
Running GetPlayer(), well after the course has finished loading, appears to work. This seems to be an issue with the way that the HTML5 output runs its JS files.
Another thing to note, SL3 now uses Booleans correctly. SL2 would use strings for bools, this means that when you grab the variable using js and check whether it's true or false, you would need to use "true" or "false". No longer in SL3.
Little things like the above should be shared with the community, otherwise we spend our already limited time trying to fix things that we shouldn't have to.
I know we've got a few reports with our team of issues with some JS triggers and HTML5 not working as they did in Storyline 2.
We're still digging into those - but I'd like to get our team looking at your example too. Can you reach out and share with our Support Engineers here?
Did this ever get resolved? I have the same issue. The story works fine in Articulate, but when we run in our environment (in an iFrame), when executing the JavaScript statement:
It was the iFrame. We viewed the page source, pulled the iFrame tag out and pasted that into the browser and the JavaScript worked fine. Turns out that since it's an iFrame:
Is there any update about this issue? (I mean SL3 HTML5 and JS files)
I get the same "ReferenceError" as Chiefy when using GetPlayer() command, as well as lmsAPI and other commands that used to work flawlessly with SL2 HTML5 publications.
We're still looking into the issues with the JS code and how it's working in Storyline 3 and 360. We'd be happy to take a look at your course too and how it's behaving. Can you reach out to our Support team here?
No change on the custom JS code folks were using in the past. This is a bit further down our roadmap, but we'll share here in the community once we have more information about what this feature will include and when it'll be ready!
In the meantime, if there are specific things you'd like to see, I'd love to know more about that! You can share it with me here and I'll get it into the hands of our Product team or you can share it with them here.
I've been working on this problem for most of my day today, and thought I'd share my findings.
I have ran a number of unit tests and can confirm that the problem of running a script that calls GetPlayer() from a Storyline object contained in an iframe is 100% reproducible. This use case always results in the following error:
GetPlayer is not a function
Conversely, when the Storyline object is loaded normally via the story.html file, the GetPlayer() function functions as outlined in the JavaScript best practices documentation.
I have tested this with four different Storyline projects.
Is there any indication of when there might be a resolution to this problem?
Thanks for checking in and sharing your findings, Matthew. There's been no change to the JS code and how it's working in Storyline 3 and 360 just yet. We'll keep you posted if there's any forward movement!
I wrote this a year ago and it's in this thread. Did you try windows.GetPlayer() ?
"It was the iFrame. We viewed the page source, pulled the iFrame tag out and pasted that into the browser and the JavaScript worked fine. Turns out that since it's an iFrame:
windows.GetPlayer() does not work for me. any other suggestions. I tried window.opener.GetPlayer() and that worked for an html file but not for a js file in same project.
It seems like there's two different issues going on.
1) GetPlayer() does not exist yet at the point you're trying to use it
Where you use the GetPlayer() can cause issues. There's a difference between putting the code inside a trigger in Storyline vs. directly in user.js or an external file. This may or may not apply to your issue but:
user.js is loaded early (this is a change from SL2) in the story_html5.html file (around line 105), meanwhile the app.min.js is loaded at the bottom of the file.
This was a change from SL2. Not sure why this change was introduced but it causes issues.
That means if you put GetPlayer() directly in user.js (even if you're using jQuery and wait until the document loaded), you can get an error because GetPlayer() does not exist yet at that point. Since the file loads earlier than the player is created, it returns an error.
You can test the difference by opening the story_html5.html file and move this line to the bottom.
However, this is a manual effort after each publish. If you put the code inside a trigger in SL, it would run. If that's the case, you know the problem was calling it too early.
2. The iframe discussion
The only time I used parent.GetPlayer() when my JS code was inside a webobject and I had to access the player from an iframe.
You can check if GetPlayer is a function by using:
One way I managed to solve this is by calling a function from within Storyline that saves the player into a variable in the external js file. This way the player is only called when the player has been loaded for sure.
Example:
In an Execute Javascript trigger call the function (i.e when timeline starts execute js):
callPlayer();
In your JS external file have:
function callPlayer(){
window.player = GetPlayer();
};
By doing this you can call the player from within any other function in your external JS file, as long as the function is called from a trigger in SL.
I´m sure that are other ways to manage the player around the iframe scope, but this is a simple way to avoid calling the player when it does not exist yet.
23 Replies
Running GetPlayer(), well after the course has finished loading, appears to work. This seems to be an issue with the way that the HTML5 output runs its JS files.
Another thing to note, SL3 now uses Booleans correctly. SL2 would use strings for bools, this means that when you grab the variable using js and check whether it's true or false, you would need to use "true" or "false". No longer in SL3.
Little things like the above should be shared with the community, otherwise we spend our already limited time trying to fix things that we shouldn't have to.
Hi chiefy,
I know we've got a few reports with our team of issues with some JS triggers and HTML5 not working as they did in Storyline 2.
We're still digging into those - but I'd like to get our team looking at your example too. Can you reach out and share with our Support Engineers here?
Good morning.
I sent a support ticket, detailing the issue. I think it could be something to do with the way that SL3's HTML5 output loads it's JS files.
Thanks Chiefy for sending that along! I see that Eloisa reached out for your case and I'll follow along as well.
Did this ever get resolved? I have the same issue. The story works fine in Articulate, but when we run in our environment (in an iFrame), when executing the JavaScript statement:
var player = window.parent.GetPlayer();
we get the following message in the web console:
window.parent.GetPlayer is not a function
The function is defined in app.min.js
Can you give me an update? Thanks
Hi Frank,
Eloisa was waiting for some additional information from Chiefy.
We do know of some issues with certain JS triggers for player functions not working as they did in Storyline 2, and it's specific to the HTML5 output.
Have you tried your JS outside of an iFrame? Perhaps using Amazons S3 or upload to Tempshare would help narrow down the issue.
It was the iFrame. We viewed the page source, pulled the iFrame tag out and pasted that into the browser and the JavaScript worked fine. Turns out that since it's an iFrame:
window.parent.GetPlayer()
won't cut it.windows.GetPlayer()
works.So you might want to share this. Thanks
Thanks Frank for sharing that here!
Hi everyone,
Is there any update about this issue? (I mean SL3 HTML5 and JS files)
I get the same "ReferenceError" as Chiefy when using GetPlayer() command, as well as lmsAPI and other commands that used to work flawlessly with SL2 HTML5 publications.
Thanks !
Hi Guillaume,
We're still looking into the issues with the JS code and how it's working in Storyline 3 and 360. We'd be happy to take a look at your course too and how it's behaving. Can you reach out to our Support team here?
Any updates on this issue?
No change on the custom JS code folks were using in the past. This is a bit further down our roadmap, but we'll share here in the community once we have more information about what this feature will include and when it'll be ready!
In the meantime, if there are specific things you'd like to see, I'd love to know more about that! You can share it with me here and I'll get it into the hands of our Product team or you can share it with them here.
Hello Every one,
I am also facing the same issue in our lMS of Storyline 3 output, for the following command "GetPlayer() is not defined" in HTML5.
Any one out there, please help me on this.
Thanks,
Vinod
I've been working on this problem for most of my day today, and thought I'd share my findings.
I have ran a number of unit tests and can confirm that the problem of running a script that calls GetPlayer() from a Storyline object contained in an iframe is 100% reproducible. This use case always results in the following error:
Conversely, when the Storyline object is loaded normally via the story.html file, the GetPlayer() function functions as outlined in the JavaScript best practices documentation.
I have tested this with four different Storyline projects.
Is there any indication of when there might be a resolution to this problem?
Thanks for checking in and sharing your findings, Matthew. There's been no change to the JS code and how it's working in Storyline 3 and 360 just yet. We'll keep you posted if there's any forward movement!
Have you tried referencing the parent with GetPlayer like this:
var SLplayer = parent.GetPlayer();
I have tried 10 hours of permutations of window access to access the function, including through the parent, the opener, etc. etc.
I'm reluctant to keep playing with it because it really does feel like it's a bug with Storyline.
Do you have a test link or project that we can look at?
I wrote this a year ago and it's in this thread. Did you try windows.GetPlayer() ?
"It was the iFrame. We viewed the page source, pulled the iFrame tag out and pasted that into the browser and the JavaScript worked fine. Turns out that since it's an iFrame:
window.parent.GetPlayer() won't cut it.
windows.GetPlayer() works.
So you might want to share this. Thanks"
windows.GetPlayer() does not work for me. any other suggestions. I tried window.opener.GetPlayer() and that worked for an html file but not for a js file in same project.
It seems like there's two different issues going on.
1) GetPlayer() does not exist yet at the point you're trying to use it
Where you use the GetPlayer() can cause issues. There's a difference between putting the code inside a trigger in Storyline vs. directly in user.js or an external file. This may or may not apply to your issue but:
user.js is loaded early (this is a change from SL2) in the story_html5.html file (around line 105), meanwhile the app.min.js is loaded at the bottom of the file.
This was a change from SL2. Not sure why this change was introduced but it causes issues.
That means if you put GetPlayer() directly in user.js (even if you're using jQuery and wait until the document loaded), you can get an error because GetPlayer() does not exist yet at that point. Since the file loads earlier than the player is created, it returns an error.
You can test the difference by opening the story_html5.html file and move this line to the bottom.
<script SRC="story_content/user.js" TYPE="text/javascript"></script>
However, this is a manual effort after each publish. If you put the code inside a trigger in SL, it would run. If that's the case, you know the problem was calling it too early.
2. The iframe discussion
The only time I used parent.GetPlayer() when my JS code was inside a webobject and I had to access the player from an iframe.
You can check if GetPlayer is a function by using:
if (typeof GetPlayer === 'function') {...}
if (typeof parent.GetPlayer === 'function') {...}
One way I managed to solve this is by calling a function from within Storyline that saves the player into a variable in the external js file. This way the player is only called when the player has been loaded for sure.
Example:
In an Execute Javascript trigger call the function (i.e when timeline starts execute js):
callPlayer();
In your JS external file have:
function callPlayer(){
window.player = GetPlayer();
};
By doing this you can call the player from within any other function in your external JS file, as long as the function is called from a trigger in SL.
I´m sure that are other ways to manage the player around the iframe scope, but this is a simple way to avoid calling the player when it does not exist yet.
I hope it helps.
Any updates on this?