Navigation Restricted or Locked using HTML5
Oct 22, 2013
I've written some simple Javascript that allows the implementation of 'Restricted' navigation in the HTML5 Storyline player menu. You can use the code as I have it here (only run the code once), or you can modify it to fully restrict navigation as 'Locked'.
Restricted Navigation:
To restrict Menu navigation to slide previously viewed, use the code below.
if (player.useCanvas) {
// [name] is the name of the event "click", "mouseover", ..
// same as you'd pass it to bind()
// [fn] is the handler function
$.fn.bindFirst = function(name, fn) {
// bind as you normally would
// don't want to miss out on any jQuery magic
this.bind(name, fn);
// Thanks to a comment by @Martin, adding support for
// namespaced events too.
var handlers = this.data('events')[name.split('.')[0]];
// take out the handler we just inserted from the end
var handler = handlers.pop();
// move it at the beginning
handlers.splice(0, 0, handler);
};
listitems = $('#slide_list li');
$.each(listitems,function(listitems,k){
j=$(k);
if(j.hasClass("has_children"))
return 1;
j.bindFirst("click",function(event){if(!$(k).hasClass("visited"))event.stopImmediatePropagation();});
});
}
14 Replies
Thanks for sharing that here Jamie, I know there are often users looking for help with Javascript so it's great to be able to point them here!
Hello,
Since I am not familiar with Java, I would like to have some information about the Javascript for restricted navigation in HTML5.
1- Do I have to put it into the "story.js" file? If yes, where?
2- Can I use it as it is (apart from the [name] element in the first line)?
Thank you!
Alessandro
if (player.useCanvas) {
// [name] is the name of the event "click", "mouseover", ..
// same as you'd pass it to bind()
// [fn] is the handler function
$.fn.bindFirst = function(name, fn) {
// bind as you normally would
// don't want to miss out on any jQuery magic
this.bind(name, fn);
// Thanks to a comment by @Martin, adding support for
// namespaced events too.
var handlers = this.data('events')[name.split('.')[0]];
// take out the handler we just inserted from the end
var handler = handlers.pop();
// move it at the beginning
handlers.splice(0, 0, handler);
};
listitems = $('#slide_list li');
$.each(listitems,function(listitems,k){
j=$(k);
if(j.hasClass("has_children"))
return 1;
j.bindFirst("click",function(event){if(!$(k).hasClass("visited"))event.stopImmediatePropagation();});
});
}
Hi Alessandro,
You may want to send Jamie a private message as I'm not certain he's still subscribed to this thread. In the meantime you may also want to review the tutorial here on using Javascript.
Thank you, Ashley, I will review again the tutorial.
Alessandro
Hi Alessandro,
If you're mainly concerned with restricting the use of the Menu/Outline in HTML since it does not allow restriction or locking as does the Flash content you should use the code referenced above.
You can actually paste the code directly into a Javascript event/trigger on one of your slides. I've included an image below as guidance. You should use only one of the sample blocks of code provided in my initial post, either 'Restricted' or 'Locked' navigation.
Restricted will prohibit the user to navigate to a slide not yet viewed. The Locked will not allow use of the Menu/Outline at all for navigation. The example below uses the Restricted code.
You should create a new Javascript trigger on your slide. Typically this would be at start of timeline. Click on the 'Script' button as shown in the Trigger Wizard below, then insert the code provided. You can test by publishing with HTML5, then launch the story_html5.html file. You may need to use Internet Explorer for local testing since some browsers seem to block local execution of Javascript.
Hi Jamie,
and thanks for your instructions: very clear!
I used the very same code as you suggested, putting it in the first slide of my project.
Then I tested it both with Chrome and Explorer 9, but still the index
is not restricted in story_html5.html.
Do you have any further suggestions?
Thank you,
Alessandro
Sorry Alessandro. I must not have gotten the subscribe email on this as I just saw your post.
I think I see the problem. I referenced 'player' which would not be defined without a 'var player = GetPlayer();' prior to it. That's likely the issue. If you're unsure, I would recommend using the Javascript console in the developer tools in Chrome. You would view an error in this case.
So, once again, I'll post some code. Please let me know if you find success.
var player = GetPlayer();
if (player.useCanvas) {
// [name] is the name of the event "click", "mouseover", ..
// same as you'd pass it to bind()
// [fn] is the handler function
$.fn.bindFirst = function(name, fn) {
// bind as you normally would
// don't want to miss out on any jQuery magic
this.bind(name, fn);
// Thanks to a comment by @Martin, adding support for
// namespaced events too.
var handlers = this.data('events')[name.split('.')[0]];
// take out the handler we just inserted from the end
var handler = handlers.pop();
// move it at the beginning
handlers.splice(0, 0, handler);
};
listitems = $('#slide_list li');
$.each(listitems,function(listitems,k){
j=$(k);
if(j.hasClass("has_children"))
return 1;
j.bindFirst("click",function(event){if(!$(k).hasClass("visited"))event.stopImmediatePropagation();});
});
}
Here's an updated and simpler version of the HTML5 restrict outline navigation method.
I've learned a bit about the player javascript since and this is a bit more efficient.
Place this on each slide at the beginning of the timeline or whenever you want to update the Outline. Running this on each slide will ensure that the list is updated to allow access to newly visited slide(s).
if (GetPlayer().useCanvas) {
$.each($("ul.slidelist li"),function(i,k){
!$(k).hasClass("has_children") && !$(k).hasClass("visited") && $(k).addClass("locked")
});
}
Thanks a lot, Jamie, now it works fine!
Alessandro
Hi Jamie,
Hopefully you see this. I'll also send you a message.
Question for you. Instead of putting this code on each slide, can I add it to each slide in the slide Master instead? This way I don't have to worry if I missed it in one of the slides.
Thanks!
Nevermind, I just tried, and it looks like the latest version of Storyline 2 now restricts the menu as it should.
Hi Bob,
With Storyline 2, the restricted menu in Storyline also controls the slide next button so that the user can't advance until the timeline has ended. If you'd want it to allow the user to advance prior to the end of the slide timeline you'll want to look at using "free" navigation.
Hi Ashley,
I prefer that it doesn't let you advance until the timeline ends. But I noticed that after you have already viewed a slide and you go back to it via the menu or the back button, you still need to wait for the timeline to end to advance again. Is there an option to set it up so that the next button is restricted on only the first time you watch that slide? Or is that something that I should add as a request?
Thanks!
Hi Bob,
Unfortunately there isn't a way to set that up - but you may want to look at the slide properties and use the "resume saved state" setting as well.
This discussion is closed. You can start a new discussion or contact Articulate Support.