Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Maintain vertical scroll position after reloading page?

Hi!

I'm using 2.0.11 / Harlowe.

I want to make a game with one very long central passage that contains hundreds of links.

However, it will be extremely cumbersome if the user has to start from the top of that page and scroll down each time s/he returns to it -- so I'd like the game to remember / store the user's most recent vertical scroll position when returning to that main passage.

My programming ability is less-than-extremely-basic; I've been looking at possible solutions for this issue on stackoverflow, etc, but I can't figure out how to implement them in Twine, and I thought I'd ask here.

Thanks so very much!

Comments

  • edited September 2016
    that's definitely doable! but it depends entirely on how you're saving the game such that they can reload it. assuming that you're not keeping track of any state whatsoever, and having clicked on any particular link won't affect the links that are visible anywhere else nor the content within any of the links, you can add the following to your Story Javascript:
    // there's nothing we can do if the browser doesn't have localStorage
    if (window.localStorage && window.localStorage['zcwScrollPosition']) {
        // sets the scroll to the previous, saved value, or to 0 if no value is saved
        $('tw-passage').scrollTop(Number(window.localStorage['zcwScrollPosition']));
    
        // creates an event that will fire when the user leaves the page
        $(window).on('beforeunload', function() {
            // saves the scroll position of the passage element in localStorage
            window.localStorage['zcwScrollPosition'] = $('tw-passage').scrollTop();
        });
    }
    

    feel free to change 'zcwScrollPosition' to whatever you like, just make sure it's unique enough that it probably won't conflict with anything else.
  • edit: you'll actually have to add that in a <script></script> block at the bottom of the big passage-with-100s-of-links; i forgot that there won't be any content in the passage when the Story Javascript executes.
  • hey furkle -- thanks so much for your response!

    for some reason, i can't get this to work... and i'm sure it's me, and not you.

    i plopped that in the Story Javascript, as well as in a <script></script> block at the bottom of the big page... and then in various combinations therein.

    when i click a link that takes me off of the big page and then return to it, i'm still at the tippy top.

    i've tried it in chrome, firefox and safari.

    in many ways, this is a very simple piece that i'm making -- it's big, but there are no variables, and not even any branching. so, to answer your questions, nothing is affected when links are clicked.

    i do plan on including a generic 'save' function, however, so that users can see how much they've read.

    i'll keep plugging away -- if you have any other suggestions, or if the mistake i've made is apparent from my reply, let me know! thanks kindly again.





  • Because of the way the conditional is written, that code will always fail unless zcwScrollPosition already exists and is not 0.

    The fix is simply to remove the check of zcwScrollPosition from the conditional, like so:
    // there's nothing we can do if the browser doesn't have localStorage
    if (window.localStorage) {
        // sets the scroll to the previous, saved value, or to 0 if no value is saved
        $('tw-passage').scrollTop(Number(window.localStorage['zcwScrollPosition']));
    
        // creates an event that will fire when the user leaves the page
        $(window).on('beforeunload', function() {
            // saves the scroll position of the passage element in localStorage
            window.localStorage['zcwScrollPosition'] = $('tw-passage').scrollTop();
        });
    }
    
  • edited September 2016
    edit: under construction
  • edited September 2016
    oops! my mistake, that's a very glaring error i missed. was sick, should've run it as a whole instead of parts.

    and now that i'm looking at this again with better eyes, and a better understanding of your use case, i'm realizing there's a few more problems, most pressingly that the stored value won't update when the scroll updates, so even if it gets set, it'll probably only be 0. so with that in mind, this should do exactly what you need (and i've tested it thoroughly this time!):
    <script>
    // there's nothing we can do if the browser doesn't have 
    // localStorage
    if (window.localStorage) {
        var ls = window.localStorage;
        // timeout needed to fire after harlowe resets document   
        // scrollTop position to 0 rather than before
        window.setTimeout(function() {
            // sets the scroll to the previous, saved value, or to 0 
            // if no value is saved.
            var val = Number(ls['zcwScrollPosition']);
            $(document).scrollTop(val);
        }, 50);
        
        // updates the saved value whenever the player scrolls.
        $(document).scroll(function(e) {
            ls['zcwScrollPosition'] = $(document).scrollTop();
        });
        
        // remove the event when the player navigates to a different
        // passage.
        $('tw-link, tw-icon.undo, tw-icon.redo').click(function() {
            $(document).off('scroll');
        });
    }
    </script>
    

    make sure you include this in the big passage itself, not the Story Javascript.

    let me know if anything doesn't work exactly right!
  • it works beautifully!

    thanks so very much for taking the time to help out, furkle and madexile -- what a great community! i really appreciate it.
  • Hi! I have a follow-up question. If anyone has a second and feels like having a look, I'd appreciate it!

    Before, I asked for help maintaining scroll position such that users could go from page A to page B and return to page A where they'd last been, rather than at the top.

    Now I'm wondering --

    Would it be possible to have the scroll position return return, on page A, to the position of the last link you visited, even if you had arrived there from a link on a different page?

    In other words could a user:

    Start on page A
    Click a link on page A that leads to page B
    Click an internal link within B to page C
    Return from page C to page A, and have page A scroll to the position of the link that leads to page C

    ....does that make sense?

    This is mainly a curiosity thing; the help you all gave before worked wonderfully. But I thought I'd ask!

    Thanks!
Sign In or Register to comment.