Detect Scrolling Panel Has Reached the Bottom - JavaScript

Jan 10, 2022

Hello. Here is a short piece of code I wrote for the scenario in Storyline where you have a scrolling panel and you want to check whether the learner has scrolled all the way to the bottom. There is, oddly, no built in trigger in Storyline for this.

I've tested this and it seems to work well, but I'd appreciate some folks trying out.

  1. Add a JavaScript trigger to the slide where you have a scrolling panel and copy the code in
  2. Set a variable in Storyline called 'scrollAtBottom' which is set to 'false' as default
  3. Change the number in line 'if (posCalc > 80)'. The number is the position of the bottom of the scrollbar button in the course window as a percentage from the top. You'll need to experiment.
  4. Set a trigger in Storyline to 'do something' when 'scrollAtBottom' changes to 'true'. (e.g. allow the learner to proceed/make a button active)
var player = GetPlayer();
var scrollbarBtn = document.querySelector('.scrollarea-btn');
var slideContainer = document.querySelector('.slide-container');

var btnPos = 0;
var slideContainerPos = 0;
var posCalc = 0;

var checkScrollbarPosition = function() {
//DETERMINE THE AMOUNT OF WHITESPACE ABOVE THE SLIDE (OFFSET)
var offset = slideContainer.getBoundingClientRect().top;

//GET POSITION OF SCROLLBAR AND SLIDE CONTAINER
btnPos = scrollbarBtn.getBoundingClientRect().bottom - offset;
slideContainerPos = slideContainer.getBoundingClientRect().bottom - offset;

//CALCULATE DISTANCE BETWEEN BOTTOM OF SCROLLBAR AND SLIDE CONTAINER AS PERCENTAGE
posCalc = (btnPos / slideContainerPos) * 100;

//FOR DEBUGGING ONLY IN CONSOLE
//console.log('btn btm pos: ' + pos);
//console.log('slide btm pos: ' + slideContainerPos);
//console.log('pos calc: ' + posCalc);

//IF POSITION OF SCROLLBAR BUTTON IS MORE THAN 80% FROM TOP OF SLIDECONTAINER SET SL VARIABLE TO TRUE
//Adapt 80% as necessary to accomodate where you want the detection to be
if (posCalc > 80) {
player.SetVar('scrollAtBottom', true);
document.removeEventListener('mouseup', checkScrollbarPosition);
}
}

document.addEventListener('mouseup', checkScrollbarPosition);
4 Replies
Jordan Glaski

Thanks for writing this.  I was able to get it to work using a posCalc of 40, and, I know it works if my NEXT button state changes to Normal.  But when I revisit the layer, the script doesn't seem to be working anymore.  The NEXT button will not change to Normal a second time.

On my main slide I have a trigger to Disable the NEXT button at the start of the slide's timeline.  Here are my triggers on the slide layer containing the scrollbar: 

"When the timeline starts on this layer, Execute JavaScript"

and

"When scrollAtBottom changes, Change state of Next Button to Normal."   

I have the layer set to "Resume Saved State".  What am I doing wrong?

Thanks.

Rachael Mordecai

It's great that it partially works at least. :-)

It's difficult to say without looking at the file, but if I were to hazard a guess it's to do with 'resuming saved state'. When the layer is revisited it might not be firing the javascript because that is set to run when the timeline starts on that layer. When you revisit to the saved state, the timeline on that layer isn't at the start any more.

Perhaps try changing the slide or layer to 'Reset layer to initial state' instead.

Jordan Glaski

After much testing, I was able to get it to work the way I need it to by doing the following:

1. Using an isolated Slide instead of a Layer, and setting the Slide to "reset to initial state".

2. Triggering my NEXT button to Disable at .25 seconds into the Timeline, because it seems that a command like this cannot occur at the same exact time as executing JavaScript, i.e., at the start of the Timeline.  (Because for my design, the desire is to enable the NEXT button upon mouse-up.)

3. Despite setting Revisiting the Slide to its "initial state", the scrollAtBottom variable doesn't appear to be reverting to FALSE.  Therefore I added a trigger to do so at the start of the slide Timeline, ahead of executing JavaScript.

4. Final trigger, because ultimately i need the NEXT button to change to normal:   "When scrollAtBottom changes, Change state of Next Button to Normal."

Success!