October 11, 2019
Volume Level Control ‘add-on’ for Captivate’s native Skin Playbars – Part 2
Comments
(5)
October 11, 2019
Volume Level Control ‘add-on’ for Captivate’s native Skin Playbars – Part 2
My name is Andreas Becker. I have a degree in Geology, but for the last 15 years worked for different Payment Service Providers as Customer Servivce Representative, Trainer, and for the last 7 years as Instructional Designer and Course Developer.I'm German, but live and work in Poland.
Guide 8 posts
Followers: 4 people
(5)

This is the piece of JavaScript code that we need to run on slide enter – first slide on the Current Window as a simple ‘Execute JavaScript’ action or as part of an advanced action.

The most important concept in the JavaScript code used here is what is called ‘event listeners’. An event listener is like a sentinel that monitors a particular element and listens for specific events to occur; that is for a particular way this element is interacted with (e.g. if it’s clicked, double-clicked, right-clicked, etc.). When such an event occurs, the event listener ‘does something’; that is he executes a specific predefined chunk of code. On setup of such an event listener one can define:

  • Which element to monitor, including by which means the target element is to be identified
  • For which event on that element to listen to
  • What should happen when the specified event on the specified element is detected

In order to establish which element should be monitored we’ll only use the getElementById method here, which uses the element’s HTML id to identify it. The general syntax for adding event listeners this way is:

document.getElementById(“[id of target element]”).addEventListener(“[event type]”, [do something]);

To learn more about JavaScript event listeners and the events they can detect, e.g. see here.

Let’s go through the code step by step. First, we need to add some event listeners that should be active right away as soon as the first slide loads:

document.getElementById(“AudioOn”).addEventListener(“mouseover”, showVolumeControl);

This monitors the playbar’s Mute button (HTML id: AudioOn), and calls the function showVolumeControl whenever it detects that the user moves the mouse over the button (mouseover). We’ll have a closer look at what the showVolumeControl actually does in a moment, but as the name implies, its main task is to show the by default hidden VolumeControl object on the stage, so it can be interacted with.

document.getElementById(“VolumeControl”).addEventListener(“mouseout”, hideVolumeControl);

This on the other hand monitors the VolumeControl object on the stage once it’s shown, and invokes the function hideVolumeControl when it detects that the user moves the mouse away from it (presumably after he is done setting the volume level). Obviously, this function’s main job is to revert the VolumeControl object on the stage back to its default hidden state. Again, we’ll see that in detail in a minute.

The third event listener in the group at the top of the code (well, actually the middle one in the order I put them in my code. The order doesn’t matter at all though):

document.getElementById(“AudioOn”).addEventListener(“click”, toggleVolumeControl);

This monitors the Mute button again, but this time it listens for mouse clicks, rather than mere mouseover events. Every time the button is clicked, it would call the function toggleVolumeControl. We’ll see later what that function does. Note that the Mute button’s original on-click functionality of muting/ unmuting the sound and toggling the state of the mute button face is not touched by this at all; the event listener for that sits somewhere buried in the playbar’s code and remains fully functional.

Below those addEventListener statements in our code follow the function objects; that is the different sets of instructions that should be carried out when the even listeners detect something.

The first function is showVolumeControl, so what is called when the user moves the mouse over the Mute button. Let’s have a look at the instructions in there.

cp.show(“VolumeControl”);

This is the actual command to show the VolumeControl object on stage.
cp.show(“[Captivate Object Name]”), same as cp.hide(“[Captivate Object Name]”), which we’ll see in a minute, are methods that come with Captivate’s JavaScript API. No need to worry about that though, since the required Captivate JavaScript API Interface Object is loaded automatically on every course load, making those methods available as if they were generic JavaScript methods.

document.getElementById(“CC”).addEventListener(“mouseover”, hideVolumeControl);
document.getElementById(“playbarSlider”).addEventListener(“mouseover”, hideVolumeControl);

Those are event listeners again, similar to those we added at the top of our code, but this time added dynamically when the function is called. They add mouseover sensivity to the Closed Captions button (HTML id: CC) and the Playbar Slide (HTML id: playbarSlider) and call the function hideVolumeControl’. This is to make sure that the Volume Control is hidden again if the learner just incidentally touches the Mute button with the mouse, while he moves the mouse horizontally over the playbar, without any real intention of changing the volume level. The Closed Caption button and the Playbar Slider are the neighboring elements to the mute button on the playbar, so the VolumeControl object will be hidden as soon as the user horizontally moves the mouse out of, and a little bit away from the mute button over those neighboring elements. See Part 1 of this blog for instruction what to do if you don’t want to display Playbar Slider and/ or Close Captions button on your playbar.

document.getElementById(“main_container”).addEventListener(“mouseleave”, hideVolumeControl);

This adds a mouseleave event listener to the main_container element, which is basically the area occupied by whole course on screen, consistent of stage area, project border and playbar. It also calls the function hideVolumeControl’. Same as mouseout, mouseleave fires when the user moves the mouse out of a certain element. We won’t discuss the difference between mouseleave and mouseout here; e.g. see here. In our solution, this assures that the Volume Control, if currently displayed, is hidden as soon as the user moves the mouse completely outside the course window (since he obviously has no intentions to further modify the volume level if he does that).

The second function hideVolumeControl, which is called when the user moves the mouse out of the VolumeControl bounding box, is basically the opposite of showVolumeControl in code syntax, as well as in effect. It reverts everything that showVolumeControl did before.

cp.hide(“VolumeControl”);

This is the actual instruction to hide the VolumeControl object on the stage.

document.getElementById(“CC”).removeEventListener(“mouseover”, hideVolumeControl);
document.getElementById(“playbarSlider”).removeEventListener(“mouseover”, hideVolumeControl);
document.getElementById(“main_container”).removeEventListener(“mouseleave”, hideVolumeControl);

These remove the event listeners that were added by the showVolumeControl function before, by using the removeEventListener method. The syntax for the removeEventListener method is exactly the same as for the addEventListener method.

Finally, there’s the toggleVoumeControl function, which is called when the user clicks the Mute button.

This function is a little more complex, in that it performs a little check if a certain condition is met, and then executes different branches, depending on whether or not that’s the case. The condition to check is whether the Mute button on the playbar is currently in unmuted state (whether the statement…

cp.movie.am.muted == false

…is correct).

cp.movie is an object in the CPM.js file, the JavaSript file that basically creates and manages the whole course web page on the fly on run time. It holds a lot of objects that reflect and control the current state of the course; among them the playbar Mute button’s state under cp.movie.am.muted.

On run time the Mute button’s native actions of muting the audio and changing its state to reflect that, will be run first, and only after that our code is run. So if the statement ‘cp.movie.am.muted == false’ happens to be incorrect, it means that audio is currently muted and the Mute button is currently in muted state. If this is the case, we want the Volume Control to be suppressed completely; that is hidden right away and not popping up again as long as sound is muted.

The second branch of our function (everything after else; see toggleVoumeControl function in the code here) takes care of that.

hideVolumeControl();

This is the very hideVolumeControl function we discussed above, which is called here from within the toggleVolumeControl function. As we’ve already seen, it hides the Volume Control, as well as removes all event listeners that are not required as long as the VolumeControl object is hidden.

document.getElementById(“AudioOn”).removeEventListener(“mouseover”, showVolumeControl);

This removes the mouseover event listener on the Mute button, assuring that the VolumeControl object is not shown on mouseover on the mute button again, as long as the sound is muted.

When the user clicks the mute button again to unmute the sound and change the button’s state to unmuted again, the condition cp.movie.am.muted == false evaluates to true, so the first branch of our toggleVolumeControl function (everything between the condition cp.movie.am.muted == false and else) is executed. And this does of course again just the opposite:

showVolumeControl();

As we already know, this shows the volume control (as in that moment the user will still be hovering over the Mute button, having just clicked it). It also restores the event listeners to  hide the volume control again when no longer used.

document.getElementById(“AudioOn”).addEventListener(“mouseover”, showVolumeControl);

This adds back in the mouseover event listener on the Mute button that would show the VolumeControl object on subsequent mouseover on the Mute button.

Note:
If you check out the function declarations in the full code here, you might noticed that in addition to what we’ve discussed, there’s a couple of statements that read:

//console.log(“[something] fired!”);

Double slash (//) flags an inline comment in JavaScript; that is whatever comes to the right of it is ignored by the browser on run time. Including those lines as executable code in their current position by deleting the two preceding slashes would report out to the browser’s console when the respective function is called, and in the case of toggleVolumeControl which of the two branches is executed. The console can be displayed by bringing up the browser’s developer tools (F12 on most browsers). Helpful sometimes during development and for trouble shooting if something does not work as expected. You can safely delete those lines completely from the code if you want.

5 Comments
2020-10-24 20:05:41
2020-10-24 20:05:41

Love that this is an option! Thank you.

Like
(1)
2020-09-23 08:09:36
2020-09-23 08:09:36

Thanks

Like
(1)
2020-01-06 19:32:00
2020-01-06 19:32:00

Thank you. I always prefer to have access to the volume when I’m the end user of a program.

Like
(2)
2020-01-06 19:30:05
2020-01-06 19:30:05

Very thorough explanation. Thank you.

Like
(1)
2019-10-16 15:18:07
2019-10-16 15:18:07

Thanks for this well documented article !

Like
(2)
Add Comment